- UserDao.java
@Repository
public class UserDao {
@Autowired
private JdbcTemplate;
public void add(String name, Integer age) {
String sql = "INSERT INTO users(NAME, age) VALUES(?,?);";
int update = jdbcTemplate.update(sql, name, age);
System.out.println("updateResult:" + update);
}
}
- UserService
@Service
public class UserService {
@Autowired
private UserDao;
public void add() {
userDao.add("lisi", 18);
int i=1/0;//可能会发生异常
userDao.add("yushengjun", 19);
}
}
- App 测试类
public class UserTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
UserService = (UserService) applicationContext.getBean("userService");
userService.add();
}
}
4.手动事物管理类
@Component
public class TransactionUtils {
// 事物管理器
@Autowired
private DataSourceTransactionManager;
public TransactionStatus begin() {
TransactionStatus transaction = dataSourceTransactionManager.getTransaction(new DefaultTransactionDefinition());
return transaction;
}
public void commit(TransactionStatus transaction) {
dataSourceTransactionManager.commit(transaction);
}
public void rollback(TransactionStatus transaction) {
dataSourceTransactionManager.rollback(transaction);
}
}
// 声明式事务
bean.xml (Spring务管理配置)
<context:component-scan base-package="com.itmayiedu"></context:component-scan>
<property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property> <property name="user" value="root"></property> <property name="password" value="root"></property>
<property name="dataSource" ref="dataSource"></property>
<bean id="dataSourceTransactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property>
<!—配置事物通知-->
<tx:advice id="txAdvice" transaction-manager="dataSourceTransactionManager">
<tx:attributes> <tx:method name="get*" read-only="true" /> <tx:method name="find*" read-only="true" /> <tx:method name="*" read-only="false" /> </tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* com.itmayiedu.service.*.*(..))" id="pt" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="pt" />
</aop:config>
注解方式实现
使用注解实现Spring的声明式事务管理,更加简单!
步骤:
1) 必须引入Aop相关的jar文件
2) bean.xml中指定注解方式实现声明式事务管理以及应用的事务管理器类
3)在需要添加事务控制的地方,写上: @Transactional
@Transactional注解:
1)应用事务的注解
2)定义到方法上: 当前方法应用spring的声明式事务
3)定义到类上: 当前类的所有的方法都应用Spring声明式事务管理;
4)定义到父类上: 当执行父类的方法时候应用事务。
使用事物注意事项
使用事物时,一定要将异常抛出外部,不然AOP环绕通知获取不到异常不能够回滚。
传播七种行为
Spring中事务的定义:
Propagation(key属性确定代理应该给哪个方法增加事务行为。这样的属性最重要的部份是传播行为。)有以下选项可供使用:
PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。(如果当前有事物,我就用当前事物,如果当前没有事物,就以非事物进行执行)
PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
@Transactional(
readOnly = false, // 读写事务
timeout = -1, // 事务的超时时间不限制
noRollbackFor = ArithmeticException.class, // 遇到数学异常不回滚
isolation = Isolation.DEFAULT, // 事务的隔离级别,数据库的默认
propagation = Propagation.REQUIRED // 事务的传播行为
)
事务传播行为:
Propagation.REQUIRED
指定当前的方法必须在事务的环境下执行;
如果当前运行的方法,已经存在事务, 就会加入当前的事务;
Propagation.REQUIRED_NEW
指定当前的方法必须在事务的环境下执行;
如果当前运行的方法,已经存在事务: 事务会挂起; 会始终开启一个新的事务,执行完后; 刚才挂起的事务才继续运行。