spring事务管理二:spring事务抽象
spring事务抽象:
spring事务抽象的关键是事务策略的概念(即你选则以何种事务来进行事务处理,JDBC事务,hibernate事务还是其他某个事务),事务策略是由org.springframework.transaction.PlatformTranscationManager接口定义(即将你选择的事务策略的具体实现类注入给该接口即可)。
PlatformTransactionManager接口:
public interface PlatformTransactionManager{ TransactionStatus getTransaction(TransactionDefinition definition) throws TransactinException; void commit(TransactionStatus status) throws TransactinException; void rollback(TransactionStatus status) throws TransactinException; }
有必要对这个接口做一下仔细的说明,最好的信息来源还是api文档:
该接口有很多具体的实现类:
All Known Implementing Classes: AbstractPlatformTransactionManager, CciLocalTransactionManager, DataSourceTransactionManager, HibernateTransactionManager, HibernateTransactionManager, JdoTransactionManager, JmsTransactionManager, JmsTransactionManager102, JpaTransactionManager, JtaTransactionManager, OC4JJtaTransactionManager, WebLogicJtaTransactionManager, WebSphereUowTransactionManager
可以看到DataSourceTransactionManager,HibernateTransactionManager(有2个HibernateTransactionManager,一个为hibernate3中的实现,另一个为hibernate4中的实现),JtaTransactionManager 等等都为该接口的具体实现
对该接口getTransaction方法的详细描述:
TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException Return a currently active transaction or create a new one, according to the specified propagation behavior. Note that parameters like isolation level or timeout will only be applied to new transactions, and thus be ignored when participating in active ones. Furthermore,not all transaction definition settings will be supported by every transaction manager: A proper transaction manager implementation should throw an exception when unsupported settings are encountered. An exception to the above rule is the read-only flag, which should be ignored if no explicit read-only mode is supported. Essentially,the read-only flag is just a hint for potential optimization.
根据传播方式(propagation behavior,很形象)会返回一个当前激活状态的事务或者创建一个新事务, 特别需要注意的是:事务隔离级别和事务超时等参数只会作用于新创建的事务,而对于激活状态的事务,这些参数将会被忽略(需要仔细考虑使用何种传播方式)。
并不是所有的设置对每个具体事务实现类都同样有效,如果具体的事务实现类发现自身不支持的设置将会报异常,但是也有一个例外:read-only,如果read-only模式不被支持,该参数将会被忽略,read-only仅仅是个潜在的优化项(无论数据库支持与否,都可以带上read-only)。
对该接口commit方法的详细描述:
void commit(TransactionStatus status) throws TransactionException Commit the given transaction,with regard to its status. If the transaction has been marked rollback-only programmatically, perform a rollback. If the transaction wasn't a new one, omit the commit for proper participation in the surrounding transaction. If a previous transaction has been suspended to be able to create a new one, resume the previous transaction after committing the new one. Note that when the commit call completes,no matter if normally or throwing an exception,the transaction must be fully completed and cleaned up. No rollback call should be expected in such a case. If this method throws an exception other than a TransactionException, then some before-commit error caused the commit attempt to fail.For example, an O/R Mapping tool might have tried to flush changes to the database right before commit,with the resulting DataAccessException causing the transaction to fail.The original exception will be propagated to the caller of this commit method in such a case.
如果不是一个新事务,则忽略提交并参与到上下文中的事务中去,如果前一个事务被挂起以便创建一个新事务,则在提交新事务后,返回前一个事务。
特别需要注意:如果commit方法调用结束后,无论调用正常还是异常,事务都会结束,rollback方法将不能再被调用。
对该接口rollback方法的详细描述:
void rollback(TransactionStatus status) throws TransactionExceptionPerform a rollback of the given transaction. If the transaction wasn't a new one, just set it rollback-only for proper participation in the surrounding transaction. If a previous transaction has been suspended to be able to create a new one, resume the previous transaction after rolling back the new one. Do not call rollback on a transaction if commit threw an exception. The transaction will already have been completed and cleaned up when commit returns,even in case of a commit exception. Consequently,a rollback call after commit failure will lead to an IllegalTransactionStateException.
这里再次提醒了commit方法调用后,无论commit返回正常还是异常,事务都已经完成并被清除,此时再调用rollback方法,将会产生异常。
org.springframework.transaction.TransactionStatus接口:Representation of the status of a transaction(事务状态,事务状态即意味着一个事务).
void flush() Flush the underlying session to the datastore, if applicable: for example,all affected Hibernate/JPA sessions. boolean hasSavepoint() Return whether this transaction internally carries a savepoint, that is, has been created as nested transaction based on a savepoint. boolean isCompleted() Return whether this transaction is completed, that is, whether it has already been committed or rolled back. boolean isNewTransaction() Return whether the present transaction is new (else participating in an existing transaction,or potentially not running in an actual transaction in the first place). boolean isRollbackOnly() Return whether the transaction has been marked as rollback-only (either by the application or by the transaction infrastructure). void setRollbackOnly() Set the transaction rollback-only.
尤其值得注意的是isComplected方法,commit和rollback都会被视为事务结束(也说明了为什么commit后就禁止rollback)。
org.springframework.transaction.TransactionDefinition接口: 事务参数
Interface that defines Spring-compliant transaction properties. Note that isolation level and timeout settings will not get applied unless an actual new transaction gets started.As only PROPAGATION_REQUIRED, PROPAGATION_REQUIRES_NEW and PROPAGATION_NESTED can cause that, it usually doesn't make sense to specify those settings in other cases. Furthermore, be aware that not all transaction managers will support those advanced features and thus might throw corresponding exceptions when given non-default values. The read-only flag applies to any transaction context, whether backed by an actual resource transaction or operating non-transactionally at the resource level. In the latter case,the flag will only apply to managed resources within the application, such as a Hibernate Session.
这里也介绍了:1,参数只在新事务中生效。2,不支持的参数会导致异常。3,read-only适用于任何事务。