当前位置:网站首页>[boutique] using dynamic agent to realize unified transaction management II
[boutique] using dynamic agent to realize unified transaction management II
2022-04-23 08:55:00 【Liang Yunliang】
DAO layer
- Interface
public interface DeptDao{
int insert(Dept dept);
}
public interface EmpDao{
int insert(Emp emp);
}
- Implementation class
public class DeptDaoImpl implements DeptDao{
@Override
public int insert(Dept dept){
QueryRunner queryRunner = new QueryRunner(TransactionManager.getDataSource());
// ....... The specific operation database realizes the operation of inserting data into the database table
}
}
public class EmpDaoImpl implements EmpDao{
@Override
public int insert(Emp emp){
QueryRunner queryRunner = new QueryRunner(TransactionManager.getDataSource());
// ....... The specific operation database realizes the operation of inserting data into the database table
}
}
Service layer
- Interface
public interface EmpService{
/** * Add employees at the same time , And the employee's Department */
int insert(Emp emp,Dept dept);
}
- Implementation class
public class EmpServiceImpl{
private DeptDao dpetDao = new DeptDaoImpl();
private EmpDao empDao = new EmpDaoImpl();
/** * Add employees at the same time , And the employee's Department */
int insert(Emp emp,Dept dept){
deptDao.insert(conn,dept);
System.out.println(3/0);
empDao.insert(conn,emp);
}
}
Transaction manager
public class TransactionManager {
private static DataSource dataSource;
// Used to place... For local threads Connection Proxy object
private static ThreadLocal<Connection> proxyConnLocal = new ThreadLocal<>();
// Used to place real... For local threads Connection object
private static ThreadLocal<Connection> realConnLocal = new ThreadLocal<>();
static {
Properties properties = new Properties();
String propertiesFile = "/mysql.properties";
try {
InputStream is = TransactionManager.class.getResourceAsStream(propertiesFile);
properties.load(is);
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
private TransactionManager() {
}
/** * Acquisition data source DataSource * * @return If you need to start a transaction , return datasource Agent for , Otherwise, return to the original datasource */
public static DataSource getDataSource() {
DataSource ds = (DataSource) Proxy.newProxyInstance(dataSource.getClass().getClassLoader(), dataSource.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("getConnection".equals(method.getName())) {
return proxyConnLocal.get();
} else {
return method.invoke(proxy, args);
}
}
});
return ds;
}
/** * Open transaction * * @throws SQLException */
public static void startTransaction() throws SQLException {
Connection conn = dataSource.getConnection();
// Set transactions not to be automatically committed
conn.setAutoCommit(false);
// Will be real Connection Object into the local thread
realConnLocal.set(conn);
// Open transaction
isTransactionEnabled.set(true);
// Set up Connection Object does not close automatically
Connection proxyConn = (Connection) Proxy.newProxyInstance(conn.getClass().getClassLoader(), conn.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("close".equals(method.getName())) {
//
return null;
} else {
return method.invoke(conn, args);
}
}
});
// take Connection Put the proxy object into the local thread
proxyConnLocal.set(proxyConn);
}
/** * Commit transaction */
public static void commitTransaction() {
DbUtils.commitAndCloseQuietly(proxyConnLocal.get());
}
/** * Roll back the transaction */
public static void rollbackTransaction() {
DbUtils.rollbackAndCloseQuietly(proxyConnLocal.get());
}
public static void release() {
DbUtils.closeQuietly(realConnLocal.get());
realConnLocal.remove();
proxyConnLocal.remove();
isTransactionEnabled.remove();
}
}
Dynamic agent transaction enhancement
public class ServiceProxy implements InvocationHandler {
private Object service;
public ServiceProxy(Object service) {
this.service = service;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object res = null;
// Whether the method is marked with transaction
try {
TransactionManager.startTransaction();
// Business methods
res = method.invoke(service, args);
TransactionManager.commitTransaction();
} catch (Exception e) {
e.printStackTrace();
TransactionManager.rollbackTransaction();
} finally {
TransactionManager.release();
}
return res;
}
public Object getProxy() {
return Proxy.newProxyInstance(service.getClass().getClassLoader(), service.getClass().getInterfaces(), this);
}
}
Test code
public static void main(String[] args) throws SQLException {
Dept dept = new Dept(20,"ACCOUNTING","NEWYORK");
Emp emp = new Emp(7369, "SMITH", "CLERK", 7902,LocalDate.of(1980, 12, 17), 800D, null, 20);
EmpService empService = EmpServiceImpl();
ServiceProxy serviceProxy = new ServiceProxy(empService);
EmpService proxy = (EmpService) serviceProxy .getProxy();
boolean addRes = proxy.add(emp,dept);
System.out.println(addRes);
}
Existing problems
Using the technology introduced in this blog basically solves the unified management of affairs . But there is a small problem with the above code , That's how all execution DeptDao Of insert() and EmpDao Of insert() Methods will have transaction support , The specific solution is to True Add a local variable to identify whether you need to return the support transaction DataSource That's all right. . Explanation of this piece , See code :https://gitee.com/hcshow/credits, There are detailed code explanations and application cases in the project .
版权声明
本文为[Liang Yunliang]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204230810365291.html
边栏推荐
- Research purpose, construction goal, construction significance, technological innovation, technological effect
- 单片机数码管秒表
- LaTeX论文排版操作
- After a circle, I sorted out this set of interview questions..
- PLC point table (register address and point table definition) cracking detection scheme -- convenient for industrial Internet data acquisition
- Technological innovation in government affairs in the construction of Digital Government
- dataBinding中使用include
- Error: cannot find or load main class
- Single chip microcomputer nixie tube stopwatch
- PLC的点表(寄存器地址和点表定义)破解探测方案--方便工业互联网数据采集
猜你喜欢

L2-3 romantic silhouette (25 points)

深度学习框架中的自动微分及高阶导数

MySQL small exercise (only suitable for beginners, non beginners are not allowed to enter)

Chris LATTNER, father of llvm: the golden age of compilers
![Flash project cross domain interception and DBM database learning [Baotou cultural and creative website development]](/img/67/1f9df4236b0aac3480836d45ab8561.png)
Flash project cross domain interception and DBM database learning [Baotou cultural and creative website development]

DJ音乐管理软件Pioneer DJ rekordbox

Reference passing 1

Mini - exercice MySQL (seulement pour les débutants, pas pour les non - débutants)

Notes on 30 steps of introduction to Internet of things of yangtao electronics STM32 III. Explanation of new cubeide project and setting

Yangtao electronic STM32 Internet of things entry 30 step notes II. Cube ide download, installation, sinicization and setting
随机推荐
Go语言自学系列 | golang结构体的初始化
Taxable income
在sqli-liabs学习SQL注入之旅(第十一关~第二十关)
Talent Plan 学习营初体验:交流+坚持 开源协作课程学习的不二路径
错误: 找不到或无法加载主类
uni-app和微信小程序中的getCurrentPages()
Illegal character in scheme name at index 0:
基于点云凸包的凹包获取方法
[58] length of the last word [leetcode]
应纳税所得额
计算神经网络推理时间的正确方法
Introduction to matlab
Download and install bashdb
深度学习框架中的自动微分及高阶导数
Single chip microcomputer nixie tube stopwatch
Latex paper typesetting operation
Yangtao electronic STM32 Internet of things entry 30 step notes IV. engineering compilation and download
Go语言自学系列 | golang结构体作为函数参数
经典题目刷一刷
完全二叉搜索树 (30 分)