定义:
一系列的动作,被当成一个单独的工作单元,要么都完成,要么全部不起作用。
之前的事务处理:JDBC与Hibernate中的事务处理——与try...catch...finally...一起用。
Spring中的事务处理:编程式,声明式。
Spring从事务管理的API中抽象出一套独立事务机制。事务管理代码能独立于特点的具体技术。
使用方法:
建立beans.xml
准备工作:配置数据源对象。
<!-- 生成数据连接池 --> <bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource"> <property name="driverClass" value="${driverClass}"></property> <property name="jdbcUrl" value="${jdbcUrl}"></property> <property name="user" value="${user}"></property> <property name="password" value="${password}"></property> <property name="minPoolSize" value="${minPoolSize}"></property> <property name="maxPoolSize" value="${maxPoolSize}"></property> <property name="initialPoolSize" value="${initialPoolSize}"></property> </bean> <!-- 生成jdbcTemplate --> <bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean>
1.配置事务管理器。
DataSourceTransactionManager类
dataSource属性注入
<!-- 配置事务管理器--> <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager"> <property name="dataSource" ref="dataSource"></property> </bean>
2.在配置文件中启用事务注解
把tx命名空间加进来。
<!-- 启动事务注解 --> <tx:annotation-driven transaction-manager="transactionManager"/>
3.添加事务注解。在类中使用的方法上添加这个注解:@Transactional
@Transactional//事务注解 @Override public void delete(String code) { workDao.deleteByInfoCode(code); infoDao.delete(code); }
下面看一个实例:
准备工作:导入c3p0、Spring框架、Mysql的jar包,并配置好
db.properties
driverClass=com.mysql.jdbc.Driver jdbcUrl=jdbc:mysql://localhost:3306/mydb user=root password= minPoolSize=5 maxPoolSize=20 initialPoolSize=5
beans.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> <!--加载数据库配置文件 db.properties--> <context:property-placeholder location="classpath:db.properties"/> <!-- 生成连接池 --> <bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource"> <property name="driverClass" value="${driverClass}"></property> <property name="jdbcUrl" value="${jdbcUrl}"></property> <property name="user" value="${user}"></property> <property name="password" value="${password}"></property> <property name="minPoolSize" value="${minPoolSize}"></property> <property name="maxPoolSize" value="${maxPoolSize}"></property> <property name="initialPoolSize" value="${initialPoolSize}"></property> </bean> <!-- 生成jdbcTemplate --> <bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> </beans>
1.做两个接口IInfoDao和IWorkDao
package maya.dao; public interface IInfoDao { public void delete(String code); }
package maya.dao; public interface IWorkDao { public void deleteByInfoCode(String code); }
2.做两个类继承以上两个接口:InfoDao和WorkDao
package maya.daolmpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import maya.dao.IInfoDao; @Repository public class InfoDao implements IInfoDao { @Autowired//自动装配beans.xml中的jdbcTemplate private JdbcTemplate jdbcTemplate; @Override public void delete(String code) { String sql = "delete from info where code=?"; jdbcTemplate.update(sql,code); //故意写一个错误代码 int n = 5/0; } }
package maya.daolmpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import maya.dao.IWorkDao; @Repository public class WorkDao implements IWorkDao { @Autowired private JdbcTemplate jdbcTemplate; @Override public void deleteByInfoCode(String code) { String sql = "delete from work where infoCode=?"; jdbcTemplate.update(sql,code); } }
3.向xml文件 添加配置信息
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> <!--扫描以下包里的类,以备使用--> <context:component-scan base-package="maya.daolmpl,maya.servicelmpl"></context:component-scan> <context:property-placeholder location="classpath:db.properties"/> <!-- 生成连接池 --> <bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource"> <property name="driverClass" value="${driverClass}"></property> <property name="jdbcUrl" value="${jdbcUrl}"></property> <property name="user" value="${user}"></property> <property name="password" value="${password}"></property> <property name="minPoolSize" value="${minPoolSize}"></property> <property name="maxPoolSize" value="${maxPoolSize}"></property> <property name="initialPoolSize" value="${initialPoolSize}"></property> </bean> <!-- 生成jdbcTemplate --> <bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 配置事务管理器 --> <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 启动事务注解 --> <tx:annotation-driven transaction-manager="transactionManager"/> </beans>
4.建立业务接口并用类继承
IInfoService接口
package maya.service; public interface IInfoService { public void delete(String code); }
InfoService类
package maya.servicelmpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import maya.dao.IInfoDao; import maya.dao.IWorkDao; import maya.daolmpl.WorkDao; import maya.service.IInfoService; @Service public class InfoService implements IInfoService { @Autowired private IWorkDao workDao; @Autowired private IInfoDao infoDao; @Transactional//为以下方法添加事务注解 @Override public void delete(String code) { workDao.deleteByInfoCode(code); infoDao.delete(code); } }
5.创建测试类并运行
package maya.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import maya.dao.IInfoDao; import maya.dao.IWorkDao; import maya.service.IInfoService; public class Test { private static ApplicationContext context = null; private static IInfoDao infoDao = null; private static IWorkDao workDao = null; private static IInfoService infoService = null; static { context = new ClassPathXmlApplicationContext("beans.xml"); infoDao = (IInfoDao)context.getBean("infoDao"); workDao = (IWorkDao)context.getBean("workDao"); infoService = (IInfoService)context.getBean("infoService"); } public static void main(String[] args) { infoService.delete("a004"); } }
结果(报错,由于除数为0):
Exception in thread "main" java.lang.ArithmeticException: / by zero
查看数据库表,并未删除成功
把事务取消掉,比如删除事务注解
package maya.servicelmpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import maya.dao.IInfoDao; import maya.dao.IWorkDao; import maya.daolmpl.WorkDao; import maya.service.IInfoService; @Service public class InfoService implements IInfoService { @Autowired private IWorkDao workDao; @Autowired private IInfoDao infoDao; //@Transactional,事务注解注销掉 @Override public void delete(String code) { workDao.deleteByInfoCode(code); infoDao.delete(code); } }
再次运行查看结果:依然报错
Exception in thread "main" java.lang.ArithmeticException: / by zero
查看数据库,“a004”已被删除
时间: 2024-10-09 20:51:08