1. Three-tier architecture (not the focus of this article, a brief introduction)
1) The user interface layer (UI Layer) is mainly responsible for providing available functions to users. The user interface layer (usually xxxview) is mainly responsible for responding to (identifying) user request operations (including UI Layer return and user input data ), the request operation calls the corresponding xxxcontroller (or xxxmanager) to complete the corresponding business logic. At this layer, it also needs to judge and process some error information (the error information is irrelevant to the database.
2) the business logic module layer (usually composed of xxxcontroller or xxxmanager class modules) is mainly responsible for computing the business logic. The business logic can be very simple, it is as simple as simply calling a save operation of xxxdao. It can also be very complicated. It is complicated to use multiple cxxxdao (or multiple table tables. That is to say, when multiple table tables are used, the business logic layer should not directly use SQL to operate the table, which will cause maintenance complexity. In this case, we should create a new xxxdao class that can operate the relevant table, let this new class complete the complex SQL (or complex Stored Procedures) required by the business logic ).
3) Dao layer (data access layer ). Mainly responsible for completing various storage and query operations. The main function is to provide different storage interfaces and queries. For example, saveuserandxxx (); getuseradnxxx (); provides simplified data access while blocking the existence of the database. the business logic layer does not need to know which database the DaO layer is using, or it's useless.
The theoretical knowledge is just like that. The key is practice. We can practice the three layers through several projects, and constantly understand the three-layer architecture from the project. It is the final principle to carefully analyze the advantages of the architecture.
2. Transactions (not a key point. A Brief Introduction)
A transaction is a program execution unit that accesses and may update various data items in the database ). Transactions have four attributes (atomicity, consistency, isolation, and persistence ).
Atomicity mainly describes the severability of a transaction, either done or not done.
Consistency mainly describes how a database changes from a consistent state to another consistent state.
Isolation mainly describes that the transaction is not executed
Durability mainly describes that once a transaction is committed, the database changes are permanent and will not be affected by other operations.
3. Use of transactions in a three-tier architecture (this is the focus)
There are also many people talking about the layer-3 architecture in which transactions should be well designed. In fact, I personally think there is no distinction between good and bad. Only one of them is suitable in a specific environment.
This problem occurs in the project I am working on.
First of all, data transactions must be at the data layer, because if transactions are not written at the data layer, data rollback will occur. However, the use of transactions in the logic layer is inevitable, and transaction management is the scope of the business, so transaction processing should be implemented in the logic layer. (This is your understanding. Thank you for your patience)
Through this analysis, we can easily know that we need to enable, commit, roll back, and close transactions in the logic layer. The implementation of transactions is actually implemented at the data layer.
I believe some people will think that transactions can only be written on the data layer. it is not normal to use sqlconnection on the business logic layer. In fact, many people agree on this point, there are also many people doing this. I am still saying that it is not correct or not. It is only suitable and not suitable. It should be determined based on the project. First, there is no problem in writing transactions at the data layer. What is the difference between the two? This is what we need to understand and is also a major factor in where we choose to write transactions.
As I said earlier, I chose to make only one connection in the transaction operations at the logic layer, at the data layer, we may not just do it once! If we perform multiple operations, the program may crash if such a connection is not properly processed.
In that case, there is no only correct standard, but only a suitable solution under certain circumstances.
---------------------------------- Split line --------------------------
If we use transactions in the logic layer, we will certainly enable database connections in the business logic layer, and our database connections will generally be written in a Database Assistant class (sqlhelper, in this way, we may be faced with creating Database Assistant class objects in the business logic layer. In this way, the coupling degree will become very high. Then we can reduce this coupling degree through the establishment of independent transactions. The specific transaction class mainly implements database connection, enabling transaction processing and closing connections.
Specific Transaction code implementation:
Using system. data; <br/> using system. data. sqlclient; <br/> using system. configuration; <br/> using system. collections; </P> <p> using system; <br/> using system. collections. generic; <br/> using system. LINQ; <br/> using system. text; <br/> using system. data. sqlclient; <br/> using system. data; <br/> using stueduadministrationmodel; <br/> using sqlhelp; </P> <p> namespace stueduadministrationdal <br/> {<br/> public class transactionmanager <br/>{< br/> // <summary> <br/> /// define the connection <br/> /// </Summary> <br/> sqlconnection = new sqlconnection (); <br/> /// <summary> <br/> // define the transaction <br/> /// </Summary> <br/> sqltransaction; </P> <p> /// <summary> <br/> // get the connection <br/> /// </Summary> <br/> /// <returns> </returns> <br/> Public sqlconnection getconnection () <br/>{</P> <p> sqlconnection. connectionstring = configurationmanager. connectionstrings ["stueduadministration"]. connectionstring; <br/> sqlconnection. open (); <br/> return sqlconnection; <br/>}</P> <p> // <summary> <br/> // start the transaction <br/> /// </Summary> <br /> Public sqltransaction tranbegin () <br/>{< br/> sqltransaction = sqlconnection. begintransaction (); <br/> return sqltransaction; <br/>}< br/> /// <summary> <br/> // submit the transaction <br/> /// </Summary> <br/> Public void trancommit () <br/>{< br/> sqltransaction. commit (); <br/>}</P> <p> // <summary> <br/> // roll back the transaction <br/> /// </Summary> <br/> Public void tranrollback () <br/>{< br/> sqltransaction. rollback (); <br/>}< br/> /// <summary> <br/> // close the connection <br/> /// </Summary> <br/> Public void close () <br/>{< br/> sqlconnection. close (); </P> <p >}< br/>
We need to implement transaction processing like this in sqlhelper code:
Public overloads function executenonquery (byval sqlstring as string, byval sqlparameters as sqlparametercollection, byval objtransaction as sqltransaction) as integer <br/> dim inttemp as integer <br/> dim cmd as sqlcommand </P> <p> try <br/> me. initializeconnection () 'initialize the connection </P> <p> cmd = new sqlcommand (sqlstring, m_objconnection) <br/> cmd. transaction = objtransaction 'transaction processing <br/> 'Add the parameters in the parameter set to cmd. <br/> call me. addsqlparameterstocommand (CMD, sqlparameters) </P> <p> inttemp = cmd. executenonquery () <br/> me. finalizeconnection () 'Close the connection (related to the way the connection object is maintained) <br/> catch ex as exception <br/> throw ex <br/> end try </P> <p> return inttemp <br/> end function <br/>
At the data layer, we only need to instantiate the sqlhelper class and pass the transaction class passed from the logic layer as well as the database connection parameters:
Private sqlconnection sqlcon; </P> <p> private sqltransaction sqltra; </P> <p> /// <summary> <br/> /// Database Assistant type <br/> /// </Summary> <br/> private sqlhelper; </P> <p> Public subcategoryscoredao (sqlconnection sqlcon, sqltransaction sqltra) <br/>{< br/> This. sqlcon = sqlcon; <br/> This. sqltra = sqltra; <br/> sqlhelper = new sqlhelper (sqlcon); <br/>}< br/> Public subcategoryscoredao () <br/>{< br/> sqlhelper = new sqlhelper ("stueduadministration"); <br/>}
To enable or disable a transaction in the logic layer:
<PRE name = "code" class = "CSHARP"> /// <summary> // Delete the score of the subcategory evaluation based on the student ID in the academic year. /// </Summary> // /<Param name = "stracademicyear"> school year </param> // <Param name = "strstuno"> Student ID </param> Public bool deletebystunoacademicyear (string stracademicyear, string strstuno) {sqlconnection sqlcon = transactionmanager. getconnection (); // obtain the connection sqltransaction sqltra = transactionmanager. tranbegin (); // transaction start try {objcategoryscoredao = new categoryscoredao (sqlcon, sqltra); iterator = new evaluateinfodao (sqlcon, sqltra); iterator = new subcategoryscoredao (sqlcon, sqltra ); objsubcategoryscoredao. deletebystunoacademicyear (stracademicyear, strstuno); objcategoryscoredao. deletebystunoacademicyear (stracademicyear, strstuno); objevaluateinfodao. deletebystunoacademicyear (stracademicyear, strstuno); transactionmanager. trancommit (); // return true for transaction commit;} catch (exception) {transactionmanager. tranrollback (); // transaction rollback throw;} finally {transactionmanager. close (); // transaction close }}</PRE> <p>
With this design, you can implement transaction management at the logic layer to implement transactions at the data layer.
The last sentence is not the best, but the most appropriate one. This blog post's point of view is just some one-sided ideas of the author. If there is anything wrong, I hope to make an ax.