Spring框架 XML配置事務(wù)控制的步驟操作

基于 XML 的聲明式事務(wù)控制
1.環(huán)境搭建
拷貝必要的 jar 包到工程的 lib 目錄

2.創(chuàng)建 spring 的配置文件并導(dǎo)入約束
這里直接給出本次測試的全部XML配置,具體細(xì)節(jié)在后面依次介紹。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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 "> <!-- 配置連接池對象 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver" /> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mybase2" /> <property name="user" value="root" /> <property name="password" value="Hudie" /> </bean> <!-- 配置JdbcTemplate模板對象 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- dao --> <bean id="userDao" class="com.gql.dao.UserDaoImp"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean> <!-- service --> <bean id="userService" class="com.gql.service.UserServiceImp"> <property name="userDao" ref="userDao"></property> </bean> <!-- 事務(wù)類/切面 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 通知: 1.告訴Spring容器采用哪種事務(wù)管理機(jī)制. 2.告訴Spring容器目標(biāo)方法采用什么樣的事務(wù)處理策略. --> <tx:advice id="tx" transaction-manager="transactionManager"> <tx:attributes> <!-- name 規(guī)定目標(biāo)方法 isolation 事務(wù)隔離級別,默認(rèn)是default propagation 傳播機(jī)制,默認(rèn)是REQUIREL --> <tx:method name="save" isolation="DEFAULT" propagation="REQUIRED" read-only="false" /> <tx:method name="up*" isolation="DEFAULT" propagation="REQUIRED" read-only="false" /> <tx:method name="de*" isolation="DEFAULT" propagation="REQUIRED" read-only="false" /> <tx:method name="get*" isolation="DEFAULT" propagation="REQUIRED" read-only="true" /> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut expression="execution (* com.gql.service.UserServiceImp.*(..))" id="point" /> <aop:advisor advice-ref="tx" pointcut-ref="point" /> </aop:config> </beans>
3.準(zhǔn)備數(shù)據(jù)庫表和實(shí)體類
user數(shù)據(jù)庫表
create database mybase2; USE mybase2; CREATE TABLE `user` ( `id` INT(10) NOT NULL AUTO_INCREMENT COMMENT '主鍵', `name` VARCHAR(20) NOT NULL DEFAULT '0', `age` INT(10) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) COLLATE='utf8_general_ci' ENGINE=InnoDB ; INSERT INTO user values(NULL,'周冬雨',21); INSERT INTO user values(NULL,'馬冬梅',18); INSERT INTO user values(NULL,'馬西梅',19);
User實(shí)體類
package com.gql.entity;
import java.io.Serializable;
/**
* 類說明:
* User實(shí)體類
* @guoqianliang1998.
*/
public class User implements Serializable {
/**
* 生成序列號
*/
private static final long serialVersionUID = -4492760954899814333L;
private int id;
private String name;
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
4.業(yè)務(wù)層接口與實(shí)現(xiàn)類
業(yè)務(wù)層接口
package com.gql.service;
import java.util.List;
import com.gql.entity.User;
/**
* 類說明:
* 業(yè)務(wù)層接口
* @guoqianliang1998.
*/
public interface UserService {
void save(User user);
void update(int id, User user);
void delete(int id);
User getUser(int id);
List<User> getUserList(int[] ids);
List<User> getUserList();
}
業(yè)務(wù)層實(shí)現(xiàn)類
package com.gql.service;
import java.util.List;
import com.gql.dao.UserDao;
import com.gql.entity.User;
/**
* 類說明:
* 業(yè)務(wù)層實(shí)現(xiàn)類
* @guoqianliang1998.
*/
public class UserServiceImp implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void save(User user) {
userDao.save(user);
int i = 1/0;
}
@Override
public void update(int id, User user) {
userDao.update(id, user);
}
@Override
public void delete(int id) {
userDao.delete(id);
}
@Override
public User getUser(int id) {
User user = userDao.getUser(id);
return user;
}
@Override
public List<User> getUserList(int[] ids) {
List<User> userList = userDao.getUserList(ids);
return userList;
}
@Override
public List<User> getUserList() {
List<User> list = userDao.getUserList();
return list;
}
}
5.數(shù)據(jù)訪問層接口與實(shí)現(xiàn)類
數(shù)據(jù)訪問層接口
package com.gql.dao;
import java.util.List;
import com.gql.entity.User;
/**
* 類說明:
* 數(shù)據(jù)訪問層接口
* @guoqianliang1998.
*/
public interface UserDao {
void save(User user);
void update(int id, User user);
void delete(int id);
User getUser(int id);
List<User> getUserList(int[] ids);
List<User> getUserList();
}
數(shù)據(jù)訪問層實(shí)現(xiàn)類
package com.gql.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import com.gql.RowMapper.UserRowMapper;
import com.gql.entity.User;
/**
* 類說明:
* 數(shù)據(jù)訪問層實(shí)現(xiàn)類
* @guoqianliang1998.
*/
public class UserDaoImp implements UserDao {
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public void save(User user) {
String sql = "INSERT INTO user values(NULL,?,?)";
jdbcTemplate.update(sql, user.getName(), user.getAge());
}
@Override
public void update(int id, User user) {
String sql = "update user set name=?,age=? WHERE id = ?";
jdbcTemplate.update(sql, user.getName(), user.getAge(), id);
}
@Override
public void delete(int id) {
String sql = "DELETE FROM user WHERE id = ?;";
jdbcTemplate.update(sql, id);
}
@Override
public User getUser(int id) {
String sql = "select * from user where id = ?";
User user = jdbcTemplate.queryForObject(sql, new RowMapper<User>() {
@Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
User user = new User();
user.setId(rs.getInt(1));
user.setName(rs.getString(2));
user.setAge(rs.getInt(3));
return user;
}
}, id);
return user;
}
@Override
public List<User> getUserList(int[] ids) {
String sql = "select * from user where id in(:ids)";
NamedParameterJdbcTemplate n = new NamedParameterJdbcTemplate(jdbcTemplate.getDataSource());
Map<String,Object> paramMap = new HashMap<String,Object>();
List list = new ArrayList();
for (int i = 0; i < ids.length; i++) {
list.add(ids[i]);
}
paramMap.put("ids", list);
List<User> userList = n.query(sql, paramMap, new RowMapper<User>(){
@Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
User user = new User();
user.setId(rs.getInt(1));
user.setName(rs.getString(2));
user.setAge(rs.getInt(3));
return user;
}
});
return userList;
// 第二種寫法↓↓↓
// StringBuilder sb = new StringBuilder();
// sb.append("SELECT * FROM user WHERE id = ?");
// for(int i=0;i<ids.length-1;i++){
// sb.append(" or id = ?");
// }
// Integer[] in = new Integer[ids.length];
// for(int i=0;i<ids.length;i++){
// in[i] = ids[i];
// }
// Object[] args = in;
// List<User> userList = jdbcTemplate.query(sb.toString(),args,new RowMapper() {
//
// @Override
// public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
// User user = new User();
// user.setId(rs.getInt(1));
// user.setName(rs.getString(2));
// user.setAge(rs.getInt(3));
// return user;
// }
// });
// return userList;
}
@Override
public List<User> getUserList() {
String sql = "select * from user";
List<User> list = jdbcTemplate.query(sql, new UserRowMapper());
return list;
}
}
6.配置c3p0數(shù)據(jù)源/業(yè)務(wù)層/數(shù)據(jù)訪問層
配置c3p0數(shù)據(jù)源
<!-- 配置連接池對象 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver" /> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mybase2" /> <property name="user" value="root" /> <property name="password" value="Hudie" /> </bean> <!-- 配置JdbcTemplate模板對象 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean>
業(yè)務(wù)層
<!-- service --> <bean id="userService" class="com.gql.service.UserServiceImp"> <property name="userDao" ref="userDao"></property> </bean>
數(shù)據(jù)訪問層
<!-- dao --> <bean id="userDao" class="com.gql.dao.UserDaoImp"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean>
7.配置事務(wù)管理器
<!-- 事務(wù)管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 注入 DataSource--> <property name="dataSource" ref="dataSource"></property> </bean>
8.配置事務(wù)的通知
事務(wù)的通知:
- 配置事務(wù)的通知來引用事務(wù)管理器
- 告訴Spring容器采用哪種事務(wù)管理機(jī)制.
- 告訴Spring容器目標(biāo)方法采用什么樣的事務(wù)處理策略.
<!-- 事務(wù)的通知: 1.告訴Spring容器采用哪種事務(wù)管理機(jī)制. 2.告訴Spring容器目標(biāo)方法采用什么樣的事務(wù)處理策略. --> <tx:advice id="tx" transaction-manager="transactionManager"> <tx:attributes> <!-- name 規(guī)定目標(biāo)方法 isolation 事務(wù)隔離級別,默認(rèn)是default propagation 傳播機(jī)制,默認(rèn)是REQUIREL --> <tx:method name="save" isolation="DEFAULT" propagation="REQUIRED" read-only="false" /> </tx:attributes> </tx:advice>
通知內(nèi)配置事務(wù)的屬性
| 屬性 | 說明 |
|---|---|
| read-only | 是否是只讀事務(wù)。默認(rèn) false,不只讀。 |
| isolation | 指定事務(wù)的隔離級別。默認(rèn)值是使用數(shù)據(jù)庫的默認(rèn)隔離級別。 |
| propagation | 指定事務(wù)的傳播行為。 |
| timeout | 指定超時時間。默認(rèn)值為:-1。永不超時。 |
| rollback-for | 用于指定一個異常,當(dāng)執(zhí)行產(chǎn)生該異常時,事務(wù)回滾。產(chǎn)生其他異常,事務(wù)不回滾。沒有默認(rèn)值,任何異常都回滾。 |
| no-rollback-for | 用于指定一個異常,當(dāng)產(chǎn)生該異常時,事務(wù)不回滾,產(chǎn)生其他異常時,事務(wù)回 |
| 滾。沒有默認(rèn)值,任何異常都回滾。 |
9.配置 AOP 切入點(diǎn)表達(dá)式
<!-- AOP切入點(diǎn)表達(dá)式 --> <aop:config> <aop:pointcut expression="execution (* com.gql.service.UserServiceImp.*(..))" id="point" /> <!-- 切入點(diǎn)表達(dá)式和事務(wù)的對應(yīng)關(guān)系 --> <aop:advisor advice-ref="tx" pointcut-ref="point" /> </aop:config>
10.配置切入點(diǎn)表達(dá)式和事務(wù)通知的對應(yīng)關(guān)系
<!-- AOP切入點(diǎn)表達(dá)式 --> <aop:config> <aop:pointcut expression="execution (* com.gql.service.UserServiceImp.*(..))" id="point" /> <!-- 切入點(diǎn)表達(dá)式和事務(wù)的對應(yīng)關(guān)系 --> <aop:advisor advice-ref="tx" pointcut-ref="point" /> </aop:config>
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
簡單了解Spring中BeanFactory與FactoryBean的區(qū)別
這篇文章主要介紹了簡單了解Spring中BeanFactory與FactoryBean的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-12-12
Java應(yīng)用層協(xié)議WebSocket實(shí)現(xiàn)消息推送
后端向前端推送消息就需要長連接,首先想到的就是websocket,下面這篇文章主要給大家介紹了關(guān)于java后端+前端使用WebSocket實(shí)現(xiàn)消息推送的詳細(xì)流程,需要的朋友可以參考下2023-02-02
dubbo集成zipkin獲取Traceid的實(shí)現(xiàn)
這篇文章主要介紹了dubbo集成zipkin獲取Traceid的實(shí)現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07
spring boot+vue 的前后端分離與合并方案實(shí)例詳解
這篇文章主要介紹了spring boot+vue 的前后端分離與合并方案實(shí)例詳解,需要的朋友可以參考下2017-11-11
簡單了解Spring Cloud搭建Config過程實(shí)例
這篇文章主要介紹了簡單了解Spring Cloud搭建Config過程實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-12-12
Springboot實(shí)現(xiàn)Shiro整合JWT的示例代碼
這篇文章主要介紹了Springboot實(shí)現(xiàn)Shiro整合JWT的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12

