我们知道加一个 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...等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)