聊一聊Spring中的 Transaction基本实现

聊一聊Spring中的 Transaction基本实现,第1张

我们知道加一个 orgspringframeworktransactionannotationTransactional 注解便可以让改方法实现事务管理(提交/回滚), 但是我们知道一个如何用编码的方式实现事务如何回滚的 抛开动态代理 , 其实事务就是动态代理实现, 但是不是我们的重点 , 我们要讲讲他为啥只支持单个数据源 还有不支持 异步 *** 作(这里的意思是在事务里开启一个新线程执行业务)

一般 *** 作都是下面这样子 , 基本流程

所以Spring帮助我们做的就是这个, 那么它一定也是这么实现的

如何启动事务呢 ,

首先需要加入依赖

SpringBoot 可以使用这个 orgspringframeworktransactionannotationEnableTransactionManagement ,对于XML配置可以去看看这个类, 他会教你咋配置

方法控制是依靠 @Transactional(transactionManager ="TransactionManager") ,

然后我们需要自己自定义实现一个 orgspringframeworktransactionPlatformTransactionManager Bean , 告诉spring事务处理的使用哪个

那么为啥加了个注解就会自动给你管理事务了呢 , 他难道不是这么做的吗

其实看 orgspringframeworkbootautoconfigurejdbcDataSourceTransactionManagerAutoConfiguration 这个地方

在你单数据源的情况下, 同时自动注入情况下, 他会默认给你生成一个 DataSourceTransactionManager

所以默认情况下, 就是走这个, 现在我们绝地不看这个 我们要自己实现

我们的问题

我们定义俩数据源, 其中就需要俩 DataSourceTransactionManager

那么写我们的service

这样子启动绝对会GG , 因为你没指定有哪个 TransactionManager

那么我们怎么做,

但是事务处理的时候 orgspringframeworkjdbcdatasourceDataSourceTransactionManager#doRollback

他有一个 Connection , 那么不和我们的connection一样 , 那么绝对回滚不了哇 因为你不是一个连接, 所以根本题绝对提交成功了 , 那么为啥 Mybatis 可以呢 所以借鉴一下,

我们看MyBatis的实现 orgmybatisspringtransactionSpringManagedTransaction 在这里, 这里缩进不了了 , 他的tab是俩空格, 我是四个, 哎 就这么看吧

所以就是在获取这里 DataSourceUtils -> orgspringframeworkjdbcdatasourceDataSourceUtils#getConnection

doGetConnection(dataSource) -> orgspringframeworkjdbcdatasourceDataSourceUtils#doGetConnection

TransactionSynchronizationManagergetResource(dataSource); -> orgspringframeworktransactionsupportTransactionSynchronizationManager#getResource

doGetResource(actualKey); -> orgspringframeworktransactionsupportTransactionSynchronizationManager#doGetResource

其实 resources 就是啥, 就是一个 ThreadLocal 维护的一个线程对象,

所以这就是为啥说事务不支持异步的原因了, 只能一个线程执行一个事务 , 不能俩线程执行 , 比如说这种,绝对不行

其实到这里我们就拿到了 ConnectionHolder 了 , orgspringframeworkjdbcdatasourceConnectionHolder 其实就是一个连接持有者, 一层封装罢了 , 多了一些额外信息

那么到这里他是如何加入进去的呢, 那就是

orgspringframeworkjdbcdatasourceDataSourceTransactionManager#doBegin 这个方法了

orgspringframeworktransactionsupportTransactionSynchronizationManager#bindResource

所以前前后后就是这个, 所以懂了吗

所以这就是 transaction 的内容 ,

我们观察源码 发现 Transaction 不支持异步 *** 作 , 不支持单任务(单个请求)多数据源, 所以不能保证多数据源的事务相关问题 ,

因此下一期我讲解多数据源 (分库分表其实也是这样子) , 或者 微服务下多数据源问题

java中DriverManager获得连接是直接获取,DataSource获取getConnection是事先通过DriverManager获取了一组连接保存在一个集合中!然后调用getConnection获取连接是直接从该集合中获取而不是去数据获取连接,当关闭连接时,也不是将连接真的关闭,而是将连接再放回DataSource保存连接的集合中!

看看是不是你是用jasperReport设计的时候是用的不是javabean的数据源?如果是用javaBean的数据源要在项目里面写一个获得所有的方法,如果没写那么你用的可能是jdbc数据源,如果写了看看是不是在整合的时候忘记数据源了。或者还有种可能是你在项目中没有添加jasperReport的架包,只要JasperReport中的lib下的所有架包加进去就可以了。

Sqlite数据库,在很多场合已经用得比较多,由于我的代码生成工具的需要,需要把Sqlite的表、字段、视图等信息获取出来,以便实现各种数据库快速生成项目工程的 *** 作。这里就需要利用C#获取Sqlite数据库的元数据了,和其他数据库一样。

为了获取Sqlite的数据库对象数据,我做了一个测试的例子来获取他的相关信息,其实它的元数据还是和Access的 *** 作方式很接近。首先我们先通过Sqlite的数据库管理工具或者Visual Studio来打开创建一些表,如下所示。

首先我们先来看看通过C#代码获取到数据库对象的 *** 作界面,如下所示。

获取表的元数据界面效果如下所示,视图和这个也查不多,很有意思的一点,就是它把创建的脚本的显示出来了,呵呵。

获取的表字段信息效果如下所示。

有了这些数据,我就很方便在我的代码生成工具Database2Sharp里面实现代码生成 *** 作了。

现在我们来看看以上实现的后台代码是如何的,来了解Sqlite的数据库获取元数据的 *** 作。

string connectionString = "";

public Form1()

{

InitializeComponent();

connectionString = stringFormat(@"Data Source={0}\OrderWaterdb;Version=3;", ApplicationStartupPath);

}

private void btnGetSchema_Click(object sender, EventArgs e)

{

using (SQLiteConnection conn = new SQLiteConnection(connectionString))

{

connOpen();

DataTable schemaTable = connGetSchema("TABLES");

thisdataGridView1DataSource = schemaTable;

}

}

获取表字段的 *** 作代码如下所示。

private void btnGetColumns_Click(object sender, EventArgs e)

{

using (SQLiteConnection conn = new SQLiteConnection(connectionString))

{

connOpen();

DataTable table = connGetSchema("TABLES");

if (table != null && tableRowsCount > 0)

{

string tableName = tableRows[0]["TABLE_NAME"]ToString();

DataTable schemaTable = GetReaderSchema(tableName, conn);

thisdataGridView1DataSource = schemaTable;

}

}

}

有JAVA的容器,才方便使用

基于Tomcat利用DataSource

1)JDBC驱动配置

直接利用JDBC编程的话,JDBC驱动放在Web app的WEB-INF/lib下就可以了。

利用DataSource的话,JDBC需要放在app服务器的类目录下:

<Tomcat安装目录>/lib

2)修改contextxml文件

在Tomcat登录DataSource有很多办法,在contextxml里追加<Resource>是最简单的。

文件: <Tomcat安装目录>/conf/Catalina/localhost/<ProjectNamexml>

内容: 追加<Resource>要素

Resource要素

- name,名字。用这个名字取得DataResource

- type,类名。一般javaxsqlDataSource

- auth,认证种类,Application或Container。Application的话,需要写认证代码。

- username

- password

- driverClassName,JDBC驱动的类名

- url,JDBC的URL

例如:

<Context>

。。。。。。。。

<Resource name="jdbc/myds" auth="Container"

type="javaxsqlDataSource"

username="sa" password=""

driverClassName="orghsqldbjdbcDriver"

url="jdbc:hsqldb:hsql://localhost"/>

。。。。。。。。

</Context>

3)使用DataSource

例子:

public void doGet(>

以上就是关于聊一聊Spring中的 Transaction基本实现全部的内容,包括:聊一聊Spring中的 Transaction基本实现、java中DriverManager跟DataSource获取getConnection有什么不同、Struts2整合JasperReport开发打印报表功能遇到问题:No dataSource specified...等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9402796.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存