1.使用 TransactionTemplate
入口代码
@Autowired
TransactionTemplate transactionTemplate;
public Long insert(User user) {
TransactionCallback<Long> tc = new TransactionCallback<Long>() {
@Override
public Long doInTransaction(TransactionStatus transactionStatus) {
userMapper.insert(user);
System.out.println("插入1");
user.setId(null);
userMapper.insert(user);
System.out.println("插入2");
return 8989L;
}
};
return transactionTemplate.execute(tc);
}
配置文件
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"/>
</bean>
dataSource指向数据源即可
2.使用 TransactionProxyFactoryBean
这种方式不侵入业务代码,但是需要给每个需要事务的对象要配置一个代理类,也是比较繁琐
业务类
public class UserServiceImpl implements IUserService {
public Long insert(User user) {
userMapper.insert(user);
System.out.println("插入1");
try {
TimeUnit.MINUTES.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
user.setId(null);
userMapper.insert(user);
System.out.println("插入2");
return 8989L;
}
}
配置bean
<bean id="userServiceImpl" class="com.bj58.car.parallel.imported.b2b.service.UserServiceImpl"/>
<!-- 配置业务层的代理 -->
<bean id="userServiceImplProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!-- 配置目标对象 -->
<property name="target" ref="userServiceImpl" />
<!-- 注入事务管理器 -->
<property name="transactionManager" ref="transactionManager"/>
<!-- 注入事务的属性 -->
<property name="transactionAttributes">
<props>
<!--
prop的格式:
* PROPAGATION :事务的传播行为
* ISOTATION :事务的隔离级别
* readOnly :只读
* -EXCEPTION :发生哪些异常回滚事务
* +EXCEPTION :发生哪些异常不回滚事务
-->
<!-- 这个key对应的就是目标类中的方法-->
<prop key="insert">PROPAGATION_REQUIRED</prop>
<!-- <prop key="transfer">PROPAGATION_REQUIRED,readOnly</prop> -->
<!-- <prop key="transfer">PROPAGATION_REQUIRED,+java.lang.ArithmeticException</prop> -->
</props>
</property>
</bean>
从配置文件中可以看到,我们为UserServiceImpl#insert方法配置了代理类UserServiceImplProxy,并且target指向了真正的业务bean
调用方
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/config_sandbox/app-config-mybatis.xml"})
public class UserServiceTest {
@Autowired
IUserService userServiceImplProxy = null;//使用接口
@Test
public void testTR() {
User user = new User();
user.setName("TR测试");
user.setPhone("1111111111");
System.out.println(userServiceImplProxy.insert(user));
System.out.println("down");
}
}
这里注意一点,需要使用接口类来承接,并且对象名字跟xml中的id一致,这样才使用了代理
3.aop xml使用方式
这种方式不会侵入业务代码,且xml配置简单
<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="append*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="modify*" propagation="REQUIRED" />
<tx:method name="edit*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="remove*" propagation="REQUIRED" />
<tx:method name="repair" propagation="REQUIRED" />
<tx:method name="delAndRepair" propagation="REQUIRED" />
<tx:method name="get*" propagation="SUPPORTS" />
<tx:method name="find*" propagation="SUPPORTS" />
<tx:method name="load*" propagation="SUPPORTS" />
<tx:method name="search*" propagation="SUPPORTS" />
<tx:method name="datagrid*" propagation="SUPPORTS" />
<tx:method name="*" propagation="SUPPORTS" />
</tx:attributes>
</tx:advice>
<aop:config >
<aop:pointcut id="p1" expression="(execution(public * com.*.service.*.*(..)))"/>
<aop:advisor advice-ref="transactionAdvice" pointcut-ref="p1"/>
</aop:config>
将要添加事务的方法在advice中添加即可
业务类更上面一样,不侵入一行代码。调用方式也很简单
4.注解方式
只使用Transactional注解即可
在配置文件中开启事务注解
<!--编程式事务-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
业务类
只需要添加Transactional注解即可
@Transactional(propagation = Propagation.REQUIRED)
public Long insert(User user) {
userMapper.insert(user);
System.out.println("插入1");
user.setId(null);
userMapper.insert(user);
System.out.println("插入2");
return 8989L;
}