工作单元模式(java)

个人理解:工作单元模式是为了解决事务性问题,即保证数据修改提交的一致性。

晚上在看到工作单元模式时,觉得比较有意思,看到的基本都是c#实现的,本着学习的态度,使用java语言实现,实现出来才发现有点蹩脚,权当记录,有时间再完善。

 1 package com.xiaolu.unitofwork;
 2
 3 import com.xiaolu.domain.AggrateRoot;
 4 import com.xiaolu.repository.UnitOfWorkRepository;
 5
 6 /**
 7  * @author : xiaolu 2018年2月5日
 8  * @todo : 工作单元接口
 9  */
10 public interface UnitOfWork {
11     public void registerAdd(AggrateRoot root, UnitOfWorkRepository repository);
12
13     public void registerModify(AggrateRoot root, UnitOfWorkRepository repository);
14
15     public void registerDelete(AggrateRoot root, UnitOfWorkRepository repository);
16
17     public void commit();
18 }
 1 package com.xiaolu.unitofworkimpl;
 2
 3 import java.sql.Connection;
 4 import java.sql.SQLException;
 5 import java.util.HashMap;
 6 import java.util.Map;
 7
 8 import com.xiaolu.datasource.DataSource;
 9 import com.xiaolu.domain.AggrateRoot;
10 import com.xiaolu.repository.UnitOfWorkRepository;
11 import com.xiaolu.unitofwork.UnitOfWork;
12
13 public class UnitOfWorkImpl implements UnitOfWork {
14     private Map<AggrateRoot, UnitOfWorkRepository> addMaps = new HashMap<AggrateRoot, UnitOfWorkRepository>();
15     private Map<AggrateRoot, UnitOfWorkRepository> deleteMaps = new HashMap<AggrateRoot, UnitOfWorkRepository>();
16     private Map<AggrateRoot, UnitOfWorkRepository> modifyMaps = new HashMap<AggrateRoot, UnitOfWorkRepository>();
17
18     @Override
19     public void registerAdd(AggrateRoot root, UnitOfWorkRepository repository) {
20         if (!addMaps.containsKey(root)) {
21             this.addMaps.put(root, repository);
22         }
23     }
24
25     @Override
26     public void registerModify(AggrateRoot root, UnitOfWorkRepository repository) {
27         if (!modifyMaps.containsKey(root)) {
28             this.modifyMaps.put(root, repository);
29         }
30     }
31
32     @Override
33     public void registerDelete(AggrateRoot root, UnitOfWorkRepository repository) {
34         if (!deleteMaps.containsKey(root)) {
35             this.deleteMaps.put(root, repository);
36         }
37     }
38
39     @Override
40     public void commit() {
41         // 在这里稍微卡顿了,c#中可以方便的使用TransactionScope事务域,但是java中没有这个概念
42         // 而事务性是建立在数据库链接的基础上,如果这里的添加,删除,修改使用的不是同一个数据库链接
43         // 那么就无法保证其事务性
44
45         Connection conn = DataSource.getConnection();
46         try {
47             conn.setAutoCommit(false);
48             doCommit(conn);
49             conn.commit();
50         } catch (SQLException e) {
51             try {
52                 conn.rollback();
53             } catch (SQLException e1) {
54                 e1.printStackTrace();
55             }
56         } finally {
57             // 这里不太舒服,更好的方式是实现java.sql.Connection接口,对原始Connection做一个封装(间接层)
58             DataSource.close();
59         }
60     }
61
62     private void doCommit(Connection conn) {
63         for (AggrateRoot root : addMaps.keySet()) {
64             addMaps.get(root).doPut(conn, root);
65         }
66
67         for (AggrateRoot root : modifyMaps.keySet()) {
68             modifyMaps.get(root).doModify(conn, root);
69         }
70
71         for (AggrateRoot root : deleteMaps.keySet()) {
72             deleteMaps.get(root).doRemove(conn, root);
73         }
74     }
75 }
package com.xiaolu.domain;
/**
 * @author : xiaolu 2018年2月5日
 * @todo   : 语义标记接口
 */
public interface AggrateRoot {
}
package com.xiaolu.repository;

import java.sql.Connection;

import com.xiaolu.domain.AggrateRoot;
import com.xiaolu.unitofwork.UnitOfWork;
import com.xiaolu.unitofworkimpl.UnitOfWorkImpl;

public abstract class UnitOfWorkRepository {

    private UnitOfWork work = new UnitOfWorkImpl();

    public void put(AggrateRoot root) {
        work.registerAdd(root, this);
    }

    public void modify(AggrateRoot root) {
        work.registerModify(root, this);
    }

    public void remove(AggrateRoot root) {
        work.registerDelete(root, this);
    }

    // 实现中不能关闭连接---
    public abstract void doPut(Connection conn, AggrateRoot root);

    // 实现中不能关闭连接---
    public abstract void doModify(Connection conn, AggrateRoot root);

    // 实现中不能关闭连接---
    public abstract void doRemove(Connection conn, AggrateRoot root);
}
 1 package com.xiaolu.domain;
 2
 3 public class Account implements AggrateRoot {
 4     private int id;
 5     // 仅作示例
 6     private int money;
 7
 8     public int getId() {
 9         return id;
10     }
11
12     public void setId(int id) {
13         this.id = id;
14     }
15
16     public int getMoney() {
17         return money;
18     }
19
20     public void setMoney(int money) {
21         this.money = money;
22     }
23
24     public void add(int money) {
25         if (money > 0) {
26             this.money += money;
27         }
28     }
29
30     public void minus(int money) {
31         if (this.money >= money) {
32             this.money -= money;
33         }
34     }
35
36 }
 1 package com.xiaolu.datasource;
 2
 3 import java.sql.Connection;
 4 import java.sql.SQLException;
 5
 6 public class DataSource {
 7     private static Connection conn = null;
 8
 9     private DataSource() {
10     }
11
12     // 不考虑多线程的情况
13     public static Connection getConnection() {
14         if (conn == null) {
15             // 创建链接---或者从连接池拿
16         }
17
18         return conn;
19     }
20
21     public static void close() {
22         try {
23             if (conn != null) {
24                 conn.close();// 关闭或放回连接池中
25             }
26         } catch (SQLException e) {
27             e.printStackTrace();
28         } finally {
29             conn = null;
30         }
31     }
32 }
 1 package com.xiaolu.service;
 2
 3 import com.xiaolu.domain.Account;
 4 import com.xiaolu.repository.UnitOfWorkRepository;
 5 import com.xiaolu.unitofwork.UnitOfWork;
 6
 7 public class TranslateAccountService {
 8     private UnitOfWork work;
 9     private UnitOfWorkRepository repository;
10
11     public TranslateAccountService(UnitOfWork work, UnitOfWorkRepository repository) {
12         this.work = work;
13         this.repository = repository;
14     }
15
16     public void translate(Account from, Account to, int money) {
17         // 省略验证
18
19         from.minus(money);
20         to.add(money);
21
22         repository.modify(from);
23         repository.modify(to);
24
25         work.commit();
26     }
27 }

这里实现主要的点在于维系一个同一个数据库连接。

原文地址:https://www.cnblogs.com/xiao-lu/p/8419690.html

时间: 2024-10-07 05:05:46

工作单元模式(java)的相关文章

MVC+EF 理解和实现仓储模式和工作单元模式

MVC+EF 理解和实现仓储模式和工作单元模式 原文:Understanding Repository and Unit of Work Pattern and Implementing Generic Repository in ASP.NET MVC using Entity Framework 文章介绍 在这篇文章中,我们试着来理解Repository(下文简称仓储)和Unit of Work(下文简称工作单元)模式.同时我们使用ASP.NET MVC和Entity Framework 搭

.NET应用架构设计—工作单元模式(摆脱过程式代码的重要思想,逆袭DDD)

阅读目录: 1.背景介绍 2.过程式代码的真正困境 3.工作单元模式的简单示例 4.总结 1.背景介绍 一直都在谈论面向对象开发,但是开发企业应用系统时,使用面向对象开发最大的问题就是在于,多个对象之间的互操作需要涉及数据库操作.两个业务逻辑对象彼此之间需要互相调用,如果之间的互相操作是在一个业务事务范围内的,很容易完成,但是如果本次业务逻辑操作涉及到多个业务对象一起协作完成时问题就来了. 在以往,我们使用过程式的代码(事务脚本模式),将所有与本次业务事务范围内相关的所有逻辑都写在一个大的代码中

[.NET领域驱动设计实战系列]专题五:网上书店规约模式、工作单元模式的引入以及购物车的实现

一.前言 在前面2篇博文中,我分别介绍了规约模式和工作单元模式,有了前面2篇博文的铺垫之后,下面就具体看看如何把这两种模式引入到之前的网上书店案例里. 二.规约模式的引入 在第三专题我们已经详细介绍了什么是规约模式,没看过的朋友首先去了解下.下面让我们一起看看如何在网上书店案例中引入规约模式.在网上书店案例中规约模式的实现兼容了2种模式的实现,兼容了传统和轻量的实现,包括传统模式的实现,主要是为了实现一些共有规约的重用,不然的话可能就要重复写这些表达式.下面让我们具体看看在该项目中的实现. 首先

工作单元模式

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Transactions; using UnitOfWork; namespace UnitOfWork { public interface IUnitOfWorkRepository { void NewItem(object item)

【.Net设计模式系列】工作单元(Unit Of Work)模式 ( 二 )

回顾 在上一篇博客[.Net设计模式系列]仓储(Repository)模式 ( 一 ) 中,通过各位兄台的评论中,可以看出在设计上还有很多的问题,在这里特别感谢 @横竖都溢 @ 浮云飞梦 2位兄台对博文中存在的问题给予指出,并提供出好的解决方案,同时也感谢其他园友的支持.欢迎各位园友对博文中出现的错误或者是设计误区给予指出,一方面防止“误人子弟”,另一方面则可以让大家共同成长. 对于上一篇博客,只是给大家提供了一种对于小型项目数据访问层的一种实现方式,通过Sql语句和传递参数来实现CRUD.并未

工作单元(Unit Of Work)模式 ( 二 )

转自 http://www.cnblogs.com/retop/p/5193394.html 理论介绍 在进行数据库添加.修改.删除时,为了保证事务的一致性,即操作要么全部成功,要么全部失败.例如银行A.B两个账户的转账业务.一方失败都会导致事务的不完整性,从而事务回滚.而工作单元模式可以跟踪事务,在操作完成时对事务进行统一提交. 理论参考:http://martinfowler.com/eaaCatalog/unitOfWork.html 具体实践 首先,讲解下设计思想:领域层通过相应的库实现

换个角度说工作单元(Unit Of Work):创建、持有与API调用

看到一些工作单元的介绍,有两种感觉,第一种是很学院,说了等于没说,我估计很多都是没有自己引入到实际的项目中去,第二种是告诉我一种结果,说这就是工作单元,但是没说为什么要这么使用.所以,本篇想要探讨的是:为什么工作单元要这么用.首先,要想将工作单元引入到自己的项目中去,急需要解决的一个问题是:工作单元的生命周期,即: 1:工作单元被谁创建,何时消亡? 2:工作单元被谁们持有? 3:工作单元的 4 个 API( MakeNew.MakeDirty.MakeRemoved.Commit )被谁调用?

[Abp 源码分析]六、工作单元的实现

0.简介 在 Abp 框架内部实现了工作单元,在这里讲解一下,什么是工作单元? Unit Of Work(工作单元)模式用来维护一个由已经被业务事物修改(增加.删除或更新)的业务对象组成的列表.Unit ?Of Work模式负责协调这些修改的持久化工作以及所有标记的并发问题.在数据访问层中采用Unit Of Work模式带来的好处是能够确保数据完整性.如果在持久化一系列业务对象(他们属于同一个事物)的过程中出现问题,那么应该将所有的修改回滚,以确保数据始终处于有效状态. 而在 Abp 的内部则是

工作单元 — Unit Of Work

在进行数据库添加.修改.删除时,为了保证事务的一致性,即操作要么全部成功,要么全部失败.例如银行A.B两个账户的转账业务.一方失败都会导致事务的不完整性,从而事务回滚.而工作单元模式可以跟踪事务,在操作完成时对事务进行统一提交. 具体实践 首先,讲解下设计思想:领域层通过相应的库实现泛型仓储接口来持久化聚合类,之后在抽象库中将对泛型仓储接口提供基础实现,并将对应的实体转化为SQl语句.这样领域层就不需要操作Sql语句即可完成CRUD操作,同时使用工作单元对事务进行统一提交. 1)定义仓储接口,包