Spring 事务管理接口
Spring 事务
Spring有声明式事务和编程式事务,声明式事务只需要提供 @Transactional的注解。然后事务的开启、提交、回滚、资源的清理都由Spring 来管理,开发人员只需要关心业务即可。
编程式事务需要使用 Spring的事务模板 TransactionTemplate或者使用直接使用底层的PlatformTransactionManager手动控制提交、回滚。
使用 TransactionTemplate 事务管理
public class SimpleService implements Service {
// single TransactionTemplate shared amongst all methods in this instance
private final TransactionTemplate transactionTemplate;
// use constructor-injection to supply the PlatformTransactionManager
public SimpleService(PlatformTransactionManager transactionManager) {
Assert.notNull(transactionManager, "The 'transactionManager' argument must not be null.");
this.transactionTemplate = new TransactionTemplate(transactionManager);
}
public Object someServiceMethod() {
return transactionTemplate.execute(new TransactionCallback() {
// the code in this method executes in a transactional context
public Object doInTransaction(TransactionStatus status) {
updateOperation1();
return resultOfUpdateOperation2();
}
});
}
}
使用PlatFormTransactionManager 的例子
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
// explicitly setting the transaction name is something that can only be done programmatically
def.setName("SomeTxName");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = txManager.getTransaction(def);
try {
// execute your business logic here
}
catch (MyException ex) {
txManager.rollback(status);
throw ex;
}
txManager.commit(status);
Spring事务传播级别
要注意的是 Spring 中的 Bean 都是无状态的单例,DAO ,Connection 是单例的,同一时刻不能被多个线程共享,否则可能有线程安全问题。
org.springframework.transaction.suport.TransactionSynchronizationManager
Spring 事务管理器通过 TransactionSynchronizationManager 来解决同一个事务中不同 DAO 获得的是同一个。
看代码吧:
事务管理器的 xml 配置 里面注入了数据源 datasource
<bean id="paymentTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
abstract="false" lazy-init="default" autowire="default">
<property name="dataSource">
<ref bean="paymentDataSource" />
</property>
</bean>
<tx:annotation-driven transaction-manager="paymentTransactionManager" />
Update 时是怎么获取 Connection 呢?
通过 TransactionSynchronizationManager 去取 Connection
事务管理器是怎么获得 Connection 呢
TransactionSynchronizationManager维护了ThreadLocal去取 Connection 其中 ThreadLocal 中的 key 是 datasource ,dataSource 是一致的,取到的Connection 就是一个
org.springframework.jdbc.datasource.DataSourceTransactionManager
事务回滚也一样
protected void doRollback(DefaultTransactionStatus status) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
Connection con = txObject.getConnectionHolder().getConnection();
if (status.isDebug()) {
logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");
}
try {
con.rollback();
}
catch (SQLException ex) {
throw new TransactionSystemException("Could not roll back JDBC transaction", ex);
}
}
同一个连接执行不同的SQL语句 ,最后在同时rollback,或者 Comit 保证了是一个原子操作
@Override
protected void doCommit(DefaultTransactionStatus status) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
Connection con = txObject.getConnectionHolder().getConnection();
if (status.isDebug()) {
logger.debug("Committing JDBC transaction on Connection [" + con + "]");
}
try {
con.commit();
}
catch (SQLException ex) {
throw new TransactionSystemException("Could not commit JDBC transaction", ex);
}
}