Solon 在编码上,是强调注解与手写并重的一个风格。它有个 @Tran
注解,用于事务管理(可以参考:《事务的全局控制及应用》)。这里,主要是讲讲它的手动处理工具类 TranUtils
。
1、看看它的接口:
public final class TranUtils {
//执行事务
public static void execute(Tran tran, RunnableEx runnable) throws Throwable;
//是否在事务中
public static boolean inTrans();
//是否在事务中且只读
public static boolean inTransAndReadOnly();
//监听事务
public static void listen(TranListener listener) throws IllegalStateException;
//获取链接
public static Connection getConnection(DataSource ds) throws SQLException;
//获取链接代理(方便,用于第三方框架事务对接)
public static Connection getConnectionProxy(DataSource ds) throws SQLException;
}
2、那怎么用它呢?
- 用它判断当前是否在事务中?
if(TranUtils.inTrans()){
//正在事务中喽...
}
- 做一个手动的事务控制(与
@Tran
注解等同效果)
@Component
public class UserService{
//@Tran(policy=TranPolicy.requires_new)
public void addUser(UserModel user)throws Throwable{
TranUtils.execute(new TranAnno().policy(TranPolicy.requires_new), ()->{
//...
});
}
}
@Controller
public class DemoController{
@Inject
UserService userService;
//父回滚,子不回滚
//
//@Tran
@Mapping("/user/add2")
pubblic void addUser2(UserModel user){
TranUtils.execute(new TranAnno(), ()->{
userService.addUser(user);
throw new RuntimeException("不让你加;但还是加了:(");
});
}
}
- 用它与 dbvisitor (或者别的第三方框架)做事务托管对接
public class SolonManagedDynamicConnection implements DynamicConnection {
private DataSource ds;
public SolonManagedDynamicConnection(DataSource ds) {
this.ds = ds;
}
@Override
public Connection getConnection() throws SQLException {
return TranUtils.getConnectionProxy(ds);
}
@Override
public void releaseConnection(Connection conn) throws SQLException {
conn.close();
}
}
3、TranUtils 是个麻雀工具
麻雀虽然,五脏具全。还可以在运行时,动态添加事务监听哦。先看看事务监听器接口:
public interface TranListener {
//顺序位
default int getIndex();
//提交之前(可以出异常触发回滚)
default void beforeCommit(boolean readOnly) throws Throwable;
//完成之前
default void beforeCompletion();
//提交之后
default void afterCommit();
//完成之后
default void afterCompletion(int status);
}
然后,我们试着做一个事务监听:
@Component
public class UserService {
@Inject
UserDao userDao;
//添加并使用事务
@Tran
public void addUserAndTran(User user){
userDao.add(user);
onUserAdd();
//这里明确知道有事务
TranUtils.listen(new TranListener() {
@Override
public void afterCompletion(int status) {
System.err.println("---afterCompletion: " + status);
}
});
}
//添加(不使用事务)
public vod addUser(User user){
userDao.add(user);
onUserAdd();
}
private void onUserAdd(){
//这里不确定是否有事务,先判断下
if(TranUtils.inTrans()){
TranUtils.listen(new TranListener() {
@Override
public void afterCompletion(int status) {
System.err.println("---afterCompletion: " + status);
}
});
}
}
}