一、transactiontemplate用法
TransactionTemplate
是 Spring 的一个功能强大的事务管理工具类。它为我们带来了很多便利,通过它我们可以不用再关心事务的传播性和隔离级别等一系列细节,而是把精力放在业务逻辑的实现上。使用 TransactionTemplate
可以让代码更加简洁、优雅和安全。
使用 TransactionTemplate
的方式非常简单,只需要在需要进行事务管理的代码块外层套一个 execute
方法就可以开启事务了,这个方法会隐式的开启一个事务,如果 execute
方法内部的代码执行成功,则事务会自动提交,否则事务会自动回滚。
public interface TransactionTemplate {
<T> T execute(TransactionCallback<T> action) throws TransactionException;
}
其中,TransactionCallback
接口的 doInTransaction
方法就是需要进行事务管理的代码块。这个接口包含一个泛型参数 T
,表示执行结果的类型,这个类型的值会被 execute
方法返回。
public interface TransactionCallback<T> {
T doInTransaction(TransactionStatus status);
}
通常情况下,我们需要在 doInTransaction
方法内部写上具体的业务逻辑代码。例如,在下面的示例中,我们采用了匿名内部类方式实现了一个 TransactionCallback
。
public class UserServiceImpl implements UserService {
private final TransactionTemplate transactionTemplate;
public UserServiceImpl(DataSource dataSource) {
this.transactionTemplate = new TransactionTemplate(new DataSourceTransactionManager(dataSource));
}
public void transferMoney(String fromUser, String toUser, int money) {
transactionTemplate.execute(new TransactionCallback<Void>() {
public Void doInTransaction(TransactionStatus status) {
try {
User from = userDao.findByName(fromUser);
User to = userDao.findByName(toUser);
from.setMoney(from.getMoney() - money);
to.setMoney(to.getMoney() + money);
userDao.update(from);
userDao.update(to);
return null;
} catch (Exception e) {
status.setRollbackOnly();
throw e;
}
}
});
}
}
在上面的 transferMoney
方法中,我们使用了 TransactionTemplate
来控制事务,从而实现了转账的功能。事务的传播性、超时时间、隔离级别等信息都可以在 TransactionTemplate
中进行配置。
二、transactionTemplate 回滚
事务处理中,有时候我们需要手动回滚一个事务,例如某些必要的校验未通过,或者抛出了某个异常。 TransactionTemplate
为我们提供了很方便的事务回滚机制。
要实现事务回滚,我们只需要在 TransactionCallback
的 doInTransaction
方法内部抛出一个运行时异常即可,例如下面的示例:
transactionTemplate.execute(new TransactionCallback<Void>() {
public Void doInTransaction(TransactionStatus status) {
try {
[...]
if (someCheckFailed) {
throw new RuntimeException("校验未通过,回滚事务");
}
[...]
} catch (Exception e) {
status.setRollbackOnly();
throw e;
}
}
});
在这个示例中,如果检测到校验未通过,就会抛出一个运行时异常,这时候 TransactionTemplate
会自动回滚事务,保证不会出现数据不一致等问题。
三、transactionTemplate 拿返回值
在实际业务应用中,我们不仅需要对事务进行控制,还需要返回一些数据给调用者。 TransactionTemplate
也为我们提供了很方便的方式来拿到执行结果。
在 TransactionCallback
的 doInTransaction
方法中,我们可以直接返回一个数据对象,这个数据对象的类型需要和 execute
方法的泛型类型参数 T
一致。例如:
String result = transactionTemplate.execute(new TransactionCallback<String>() {
public String doInTransaction(TransactionStatus status) {
try {
[...]
String someResult = someService.doSomething();
[...]
return someResult;
} catch (Exception e) {
status.setRollbackOnly();
throw e;
}
}
});
在这个示例中,我们通过返回一个 String
类型的结果来演示如何拿到执行结果。
四、transactionTemplate 隔离级别
在多线程环境下,当多个事务并发执行的时候,可能会出现数据不一致的问题。这时候,事务的隔离级别就非常重要了,它定义了事务之间的可见性和并发性。Spring 的 TransactionTemplate
为我们提供了五种隔离级别,我们可以根据实际业务场景来选择合适的隔离级别。
五种隔离级别分别为:
ISOLATION_DEFAULT
:使用底层数据库的默认隔离级别,通常为ISOLATION_READ_COMMITTED
。ISOLATION_READ_UNCOMMITTED
:读取未提交数据。ISOLATION_READ_COMMITTED
:只能读取已提交数据。ISOLATION_REPEATABLE_READ
:可重复读,事务执行期间,不能修改已读取的数据。ISOLATION_SERIALIZABLE
:串行化,所有事务按照顺序依次执行。
我们可以在 TransactionTemplate
中使用 setIsolationLevel
方法来指定隔离级别,例如:
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
transactionTemplate.setTimeout(30);
在这个示例中,我们将事务的隔离级别设置为 ISOLATION_READ_UNCOMMITTED
,意味着可以读取未提交的数据。同时,我们还定义了事务的传播行为为 PROPAGATION_REQUIRED
,超时时间为 30 秒。
原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/237099.html