|
From: <jue...@we...> - 2004-06-19 10:02:06
|
Thomas, Alef, Colin, everybody,
=20
Motivated by Rod, I've added support for nested transactions to our =
transaction infrastructure, via the new propagation behavior =
PROPAGATION_NESTED. The transaction manager needs to open a true nested =
transaction which can be rolled back individually while still being able =
to continue with the surrounding transaction.
=20
Furthermore, application code can also use custom savepoints: The =
TransactionStatus interface now has a SavepointManager superinterface, =
which provides generic means to create savepoints and roll back to them. =
This is only intended for advanced needs where the declarative nested =
transaction model is not sufficient.
=20
DataSourceTransactionManager implements nested transaction support via =
JDBC 3.0 Savepoints: basically, create a Savepoint on nested transaction =
begin, release it on nested transaction commit, roll back to it on =
nested transaction rollback. Of course, DataSourceTransactionManager is =
still compatible with JDBC 2.0 if not using nested transactions.
=20
HibernateTransactionManager and JdoTransactionManager offer support for =
JDBC 3.0 Savepoints too, but it's deactivated by default there: =
Savepoints are just able to roll back the underlying JDBC Connection, =
not the Session respectively PersistenceManager with its object cache. =
Savepoints are still useful for JDBC access code that participates in a =
Hibernate/JDO transaction, though, when used with care.
=20
All of this is already fully covered by unit tests. Unfortunately, I =
don't have a database with savepoint support available here, i.e. no =
Oracle; so I've just been able to test that it fails nicely against =
MySQL (on JDK 1.4 and 1.3). Thomas, do you have a chance to test this =
against a live database?
=20
An example for how PROPAGATION_NESTED is supposed to work. Note that the =
nested transaction sets the rollback-only flag: This should just cause a =
rollback of the second update statement but still allow the surrounding =
transaction to commit the first update statement.
=20
DataSource ds =3D ...;
final PlatformTransactionManager tm =3D new =
DataSourceTransactionManager(ds);
final JdbcTemplate jt =3D new JdbcTemplate(ds);
TransactionTemplate tt1 =3D new TransactionTemplate(tm);
=
tt1.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
tt1.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus =
status) {
jt.update("first update statement");
TransactionTemplate tt1 =3D new TransactionTemplate(tm);
=
tt1.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED);
tt1.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus =
status) {
jt.update("second update statement");
status.setRollbackOnly();
}
});
}
});
An example for the same effect via manual savepoint management:
=20
TransactionTemplate tt1 =3D new TransactionTemplate(tm);
=
tt1.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
tt1.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus =
status) {
jt.update("first update statement");
Object savepoint =3D status.createSavepoint();
jt.update("second update statement");
status.rollbackToSavepoint(savepoint);
}
});
=20
Juergen
=20
|
|
From: Thomas R. <tho...@tr...> - 2004-06-19 13:52:20
|
Yes, it does work against a 9i db using both 9i (9.2.0.3) and 10g
drivers. Nice job coding in the "dark" :-)
9i driver complains about not supporting "releaseSavepoint"
(java.sql.SQLException: Unsupported feature), but it still seems to
work. 10g driver had no problems at all.
PostgreSQL (7.4) failed nicely. No support for savepoints.
MS SQL Server (driver 2.2.0029) errored out with a
"java.lang.AbstractMethodError". It must only support JDBC 2 --
supportsSavepoints was added in JDBC 3. I added a try/catch for that to
provide a nicer error.
Any way you can get this to work in a managed environment with JTA :-)
Thomas
jürgen höller [werk3AT] wrote:
>Thomas, Alef, Colin, everybody,
>
>Motivated by Rod, I've added support for nested transactions to our transaction infrastructure, via the new propagation behavior PROPAGATION_NESTED. The transaction manager needs to open a true nested transaction which can be rolled back individually while still being able to continue with the surrounding transaction.
>
>Furthermore, application code can also use custom savepoints: The TransactionStatus interface now has a SavepointManager superinterface, which provides generic means to create savepoints and roll back to them. This is only intended for advanced needs where the declarative nested transaction model is not sufficient.
>
>DataSourceTransactionManager implements nested transaction support via JDBC 3.0 Savepoints: basically, create a Savepoint on nested transaction begin, release it on nested transaction commit, roll back to it on nested transaction rollback. Of course, DataSourceTransactionManager is still compatible with JDBC 2.0 if not using nested transactions.
>
>HibernateTransactionManager and JdoTransactionManager offer support for JDBC 3.0 Savepoints too, but it's deactivated by default there: Savepoints are just able to roll back the underlying JDBC Connection, not the Session respectively PersistenceManager with its object cache. Savepoints are still useful for JDBC access code that participates in a Hibernate/JDO transaction, though, when used with care.
>
>All of this is already fully covered by unit tests. Unfortunately, I don't have a database with savepoint support available here, i.e. no Oracle; so I've just been able to test that it fails nicely against MySQL (on JDK 1.4 and 1.3). Thomas, do you have a chance to test this against a live database?
>
>An example for how PROPAGATION_NESTED is supposed to work. Note that the nested transaction sets the rollback-only flag: This should just cause a rollback of the second update statement but still allow the surrounding transaction to commit the first update statement.
>
> DataSource ds = ...;
> final PlatformTransactionManager tm = new DataSourceTransactionManager(ds);
> final JdbcTemplate jt = new JdbcTemplate(ds);
>
> TransactionTemplate tt1 = new TransactionTemplate(tm);
> tt1.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
> tt1.execute(new TransactionCallbackWithoutResult() {
> protected void doInTransactionWithoutResult(TransactionStatus status) {
> jt.update("first update statement");
>
> TransactionTemplate tt1 = new TransactionTemplate(tm);
> tt1.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED);
> tt1.execute(new TransactionCallbackWithoutResult() {
> protected void doInTransactionWithoutResult(TransactionStatus status) {
> jt.update("second update statement");
> status.setRollbackOnly();
> }
> });
> }
> });
>
>An example for the same effect via manual savepoint management:
>
> TransactionTemplate tt1 = new TransactionTemplate(tm);
> tt1.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
> tt1.execute(new TransactionCallbackWithoutResult() {
> protected void doInTransactionWithoutResult(TransactionStatus status) {
> jt.update("first update statement");
>
> Object savepoint = status.createSavepoint();
> jt.update("second update statement");
> status.rollbackToSavepoint(savepoint);
>
> }
> });
>
>Juergen
>
>
>
>-------------------------------------------------------
>This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
>Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
>Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
>REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND
>_______________________________________________
>Springframework-developer mailing list
>Spr...@li...
>https://lists.sourceforge.net/lists/listinfo/springframework-developer
>
>
>
>
>
|
|
From: Thomas R. <tho...@tr...> - 2004-06-19 14:10:12
|
Ooops, the 10g driver complains about the releaseSavepoint as well -
must have missed that in the log earlier. Still works though.
Thomas
Thomas Risberg wrote:
> Yes, it does work against a 9i db using both 9i (9.2.0.3) and 10g
> drivers. Nice job coding in the "dark" :-)
>
> 9i driver complains about not supporting "releaseSavepoint"
> (java.sql.SQLException: Unsupported feature), but it still seems to
> work. 10g driver had no problems at all.
>
> PostgreSQL (7.4) failed nicely. No support for savepoints.
>
> MS SQL Server (driver 2.2.0029) errored out with a
> "java.lang.AbstractMethodError". It must only support JDBC 2 --
> supportsSavepoints was added in JDBC 3. I added a try/catch for that
> to provide a nicer error.
>
> Any way you can get this to work in a managed environment with JTA :-)
>
> Thomas
>
>
> jürgen höller [werk3AT] wrote:
>
>> Thomas, Alef, Colin, everybody,
>>
>> Motivated by Rod, I've added support for nested transactions to our
>> transaction infrastructure, via the new propagation behavior
>> PROPAGATION_NESTED. The transaction manager needs to open a true
>> nested transaction which can be rolled back individually while still
>> being able to continue with the surrounding transaction.
>>
>> Furthermore, application code can also use custom savepoints: The
>> TransactionStatus interface now has a SavepointManager
>> superinterface, which provides generic means to create savepoints and
>> roll back to them. This is only intended for advanced needs where the
>> declarative nested transaction model is not sufficient.
>>
>> DataSourceTransactionManager implements nested transaction support
>> via JDBC 3.0 Savepoints: basically, create a Savepoint on nested
>> transaction begin, release it on nested transaction commit, roll back
>> to it on nested transaction rollback. Of course,
>> DataSourceTransactionManager is still compatible with JDBC 2.0 if not
>> using nested transactions.
>>
>> HibernateTransactionManager and JdoTransactionManager offer support
>> for JDBC 3.0 Savepoints too, but it's deactivated by default there:
>> Savepoints are just able to roll back the underlying JDBC Connection,
>> not the Session respectively PersistenceManager with its object
>> cache. Savepoints are still useful for JDBC access code that
>> participates in a Hibernate/JDO transaction, though, when used with
>> care.
>>
>> All of this is already fully covered by unit tests. Unfortunately, I
>> don't have a database with savepoint support available here, i.e. no
>> Oracle; so I've just been able to test that it fails nicely against
>> MySQL (on JDK 1.4 and 1.3). Thomas, do you have a chance to test this
>> against a live database?
>>
>> An example for how PROPAGATION_NESTED is supposed to work. Note that
>> the nested transaction sets the rollback-only flag: This should just
>> cause a rollback of the second update statement but still allow the
>> surrounding transaction to commit the first update statement.
>>
>> DataSource ds = ...;
>> final PlatformTransactionManager tm = new
>> DataSourceTransactionManager(ds);
>> final JdbcTemplate jt = new JdbcTemplate(ds);
>>
>> TransactionTemplate tt1 = new TransactionTemplate(tm);
>> tt1.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
>> tt1.execute(new TransactionCallbackWithoutResult() {
>> protected void doInTransactionWithoutResult(TransactionStatus
>> status) {
>> jt.update("first update statement");
>>
>> TransactionTemplate tt1 = new TransactionTemplate(tm);
>>
>> tt1.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED);
>> tt1.execute(new TransactionCallbackWithoutResult() {
>> protected void doInTransactionWithoutResult(TransactionStatus
>> status) {
>> jt.update("second update statement");
>> status.setRollbackOnly();
>> }
>> });
>> }
>> });
>>
>> An example for the same effect via manual savepoint management:
>>
>> TransactionTemplate tt1 = new TransactionTemplate(tm);
>> tt1.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
>> tt1.execute(new TransactionCallbackWithoutResult() {
>> protected void doInTransactionWithoutResult(TransactionStatus
>> status) {
>> jt.update("first update statement");
>>
>> Object savepoint = status.createSavepoint();
>> jt.update("second update statement");
>> status.rollbackToSavepoint(savepoint);
>>
>> }
>> });
>>
>> Juergen
>>
>>
>>
>> -------------------------------------------------------
>> This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
>> Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
>> Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
>> REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND
>> _______________________________________________
>> Springframework-developer mailing list
>> Spr...@li...
>> https://lists.sourceforge.net/lists/listinfo/springframework-developer
>>
>>
>>
>>
>>
>
>
>
> -------------------------------------------------------
> This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
> Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
> Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
> REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND
> _______________________________________________
> Springframework-developer mailing list
> Spr...@li...
> https://lists.sourceforge.net/lists/listinfo/springframework-developer
>
>
>
|
|
From: Rod J. <rod...@in...> - 2004-06-19 21:17:03
|
Thomas > Any way you can get this to work in a managed environment with JTA :-) Not without: - having all savepoint-capable resources (not unlikely, for example, if you're using DB2 and Oracle, say) - being able to get at the underlying API of the transaction manager, rather than purely via JTA. This is conceivable, but won't make the 1.1 timeframe. - not having an ORM tool like Hibernate, which doesn't understand savepoints, involved in the transactions. Otherwise its cache will be unaware of the reversion to a savepoint. Of course if the ORM tool is only used for data that isn't modified and reverted that's fine. I think these transaction enhancements are an important feature, although it's important to understand that they work only in certain scenarios. Basically we're taking a different approach to JTA (but of course without sacrificing our excellent support for JTA). The JTA philosophy is that "nested transactions are not supported by all resource managers, so forget about them, or use the resource manager's local transaction API directly." We're saying: "here's a feature that works with some resource managers in certain situations. We provide access to it." This is an important distinction. For example, I have a client who have a huge Oracle database. They need to do very high transaction volumes, but they will never use another transactional resources. Yet some of the transaction processing they need to do is complex and requires nested transactions, not PROPAGATION_NEW. It's hard to work around that; they've paid for the database, and should be able to use its features without reverting to direct JDBC transaction management, loss of declarative transactions etc. Those parts of their tx processing use JDBC, rather than any ORM solution, to absolutely minimize overhead. This is what led to my desire for this feature: I can see a significant business value, in a certain range of situations. Hopefully, over time, the range of resources supporting sophisticated tx management concepts will grow. Rgds Rod |