First, Introduction:
The previous one mentions the concepts associated with JDBC transactions. It is understood that transactions should have acid characteristics. So for javaweb development, the method of a service layer should be a transaction and should be atomic in nature. In particular, a method that calls multiple DAO layers is required in a service method. It should be ensured that these multiple invocations of the DAO method must be executed successfully. Otherwise, all execution fails. For example, the method of transfer of service method of banking service, need to update the source to account information through DAO call to reduce the specified amount, and then call DAO to update the target account information to increase the specified amount.
Then the following guarantee is required when calling across the DAO layer, what is the acid characteristic of the transaction?
Second, the solution method of thinking:
The Acid property of the transaction is guaranteed, and by default it is an automatic commit state to manipulate the database with JDBC. You must change the transaction commit to manual commit. By the program to control what is submitted to the database together. In general, the default isolation level for MySQL, SQL Server and Oracle is the repeatable read level. You can avoid dirty reads and non-repeatable reads. So the key to control is the commit and rollback of the transaction.
So how is a service method called across multiple DAO methods guaranteed to be a transaction? The first thing to ensure is that the same connection connection is possible to guarantee the same transaction. The next thing to look at is how to get the same connection in multiple DAO layers. Let the whole application have only one connection although the same connection can be solved, the application becomes single-threaded. I'm sure you can't. So how do you ensure that the connection obtained within the same thread are the same object in many threads? Threadlocal class to help, it can provide thread local variables. The objects that are placed into this threadlocal are identical to the objects that are guaranteed to be on the same thread.
Workaround: Just write a transactionutils class that has a private static threadlocal TL object. And the static Getconnction method body, first determine whether there are connection objects in the TL object, there is a direct return to the connection in the TL. Does not exist, it first obtains a connection object from the data source and then puts it into the TL, and then returns the Connection object. In addition, the Transactionutils class also needs to provide opentransaction method, commit method, Rollback method, Opentransaction, Commit and rollback need connection object to find the Getconnection method of this class directly.
Next to the service layer, first call the Transactionutils class of the Opentransaction method, and then all the DAO layer call methods are try ... Under the catch...finally. The rollback method of the Transactionutils class is called in the catch. The commit method of the Transactionutils class is called in finally.
and the DAO layer obtains the connection to find the Transactionutils class Getconnection method, to confirm that obtains all is the same connection object.
Three, the sample code is as follows:
01public class Transactionutil {
The private static threadlocal<connection> TL = new threadlocal<connection> ();
The private static DataSource DS;
04
static {
try {
InputStream in = DbcpUtil.class.getClassLoader ()
getResourceAsStream ("Dbcpconfig.properties");
Props Properties = new properties ();
Ten props.load (in);
ds = Basicdatasourcefactory.createdatasource (props);
The catch (Exception e) {
throw new Exceptionininitializererror (e);
14}
15}
16
public static DataSource Getdatasource () {
return DS;
19}
20
public static Connection getconnection () {
Connection conn = Tl.get (); Obtained from Threadloacl, if no more from DataSource
if (conn = = null) {
try {
conn = Ds.getconnection ();
Tl.set (conn); Save to Threadloacl.
(SQLException e) {
E.printstacktrace ();
29}
30}
Return conn;
32}
33
public static void StartTransaction () {
try {
Connection conn = Tl.get ();
PNS if (conn = = null) {//If not in Threadloacl, get from DataSource
conn = Ds.getconnection ();
Tl.set (conn); Deposit
40}
Conn.setautocommit (FALSE);
* catch (Exception e) {
E.printstacktrace ();
44}
45}
46
public static Voidrollback () {<span style= "font-family: ' Courier New '; ">//ROLLBACK TRANSACTION, under Service layer try DAO layer, call ROLLBAKC method at catch point </span>
try {
Connection conn = Tl.get ();
IF (conn! = null)
Wuyi Conn.rollback ();
Exception} catch (e) {
E.printstacktrace ();
54}
55}
56
$ public static voidcommit () {<span style= "font-family: ' Courier New '; ">//in finally calls the Submit Commint method </span>
try {
Connection conn = Tl.get ();
IF (conn! = null)
Conn.commit ();
Exception} catch (e) {
E.printstacktrace ();
64}
65}
66
All public static void release () {
try {
Connection conn = Tl.get ();
IF (conn! = null) {
Conn.close ();
Tl.remove ();
73}
Exception} catch (e) {
E.printstacktrace ();
76}
77}
78
79}
JDBC Transaction Control