Spring_事務管理(轉賬案例)
阿新 • • 發佈:2018-12-01
實現一個轉賬的業務:
OrderDao.java:
package h.l.tx; import org.springframework.jdbc.core.JdbcTemplate; public class OrderDao { private JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } // 模擬轉賬功能:少錢的方法 public void desMoney() { String sql = "update account set balance=balance-? where username=?"; jdbcTemplate.update(sql, 1000, "zs"); } // 模擬轉賬功能:多錢的方法 public void incMoney() { String sql = "update account set balance=balance+? where username=?"; jdbcTemplate.update(sql, 1000, "ls"); } }
OrderService.java:
package h.l.tx; public class OrderService { private OrderDao orderDao; public void setOrderDao(OrderDao orderDao) { this.orderDao = orderDao; } // 業務邏輯:轉賬功能 public void accountMoney() { // 甲少錢 orderDao.desMoney(); //手動新增異常 int i=1/0; // 乙多錢 orderDao.incMoney(); } }
Spring配置檔案:ApplicationContext.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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here --> <!-- 配置c3p0連線池 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <!-- 注入屬性 --> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/name?useSSL=true"></property> <property name="user" value="root"></property> <property name="password" value="root"></property> </bean> <!-- 配置OrderService和OrderDao物件 --> <bean id="orderService" class="h.l.tx.OrderService"> <property name="orderDao" ref="orderDao"></property> </bean> <bean id="orderDao" class="h.l.tx.OrderDao"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean> <!-- 建立JdbcTemplate物件 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> </beans>
測試程式:
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
class OrderServiceTest {
ApplicationContext context;
@BeforeEach
void setUp() throws Exception {
context = new ClassPathXmlApplicationContext(
"springConfig/ApplicationContext.xml");
}
@Test
void test() {
OrderService orderService=(OrderService)context.getBean("orderService");
orderService.accountMoney();
}
}
執行了上述程式碼之後,會出現個很嚴重的問題,就是單元測試沒有通過,因為int i=1/0;但是在資料庫中zs的錢已經少了1000,,因此解決方法就是加上事務管理:出現異常時,回滾。下面給該功能新增事務功能:
配置檔案方式實現:修改上面的ApplicationContext.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:aop="http://www.springframework.org/schema/aop"
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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 配置c3p0連線池 -->
<bean id="dataSource"
class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 注入屬性 -->
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl"
value="jdbc:mysql://localhost:3306/name?useSSL=true"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
<!-- 配置事務管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入dataSource -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置事務增強 -->
<tx:advice id="txadvice" transaction-manager="transactionManager">
<!-- 做事務操作 -->
<tx:attributes>
<!-- 設定進行事務操作的方法匹配規則 -->
<tx:method name="account*"/>
</tx:attributes>
</tx:advice>
<!-- 配置切面 -->
<aop:config>
<!-- 配置切入點 -->
<aop:pointcut expression="execution(* h.l.tx.OrderService.*(..))" id="pointcut1"/>
<aop:advisor advice-ref="txadvice" pointcut-ref="pointcut1"/>
</aop:config>
<!-- 配置OrderService和OrderDao物件 -->
<bean id="orderService" class="h.l.tx.OrderService">
<property name="orderDao" ref="orderDao"></property>
</bean>
<bean id="orderDao" class="h.l.tx.OrderDao">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<!-- 建立JdbcTemplate物件 -->
<bean id="jdbcTemplate"
class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
註解方式實現:
第一步:修改ApplicationContext.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:aop="http://www.springframework.org/schema/aop"
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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 配置c3p0連線池 -->
<bean id="dataSource"
class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 注入屬性 -->
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl"
value="jdbc:mysql://localhost:3306/name?useSSL=true"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
<!-- 配置事務管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入dataSource -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 開啟事務註解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- 配置OrderService和OrderDao物件 -->
<bean id="orderService" class="h.l.tx.OrderService">
<property name="orderDao" ref="orderDao"></property>
</bean>
<bean id="orderDao" class="h.l.tx.OrderDao">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<!-- 建立JdbcTemplate物件 -->
<bean id="jdbcTemplate"
class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
第二步在需要新增事務功能的類上加上@Transactional註解:如下即可:
package h.l.tx;
import org.springframework.transaction.annotation.Transactional;
@Transactional
public class OrderService {
private OrderDao orderDao;
public void setOrderDao(OrderDao orderDao) {
this.orderDao = orderDao;
}
// 業務邏輯:轉賬功能
public void accountMoney() {
// 甲少錢
orderDao.desMoney();
//出現異常
int i=1/0;
// 乙多錢
orderDao.incMoney();
}
}
注:以上文章僅是個人學習過程總結,若有不當之處,望不吝賜教