How to do MySQL Transaction over two different servers with c# - c#

I am making a winform application in c#. I need to update/insert or delete two different tables in two different databases on two different servers and I want to do it with transaction (If update in one database fails, the other will be rolled back.)
How can I do it, please give some code in c# and also state whether it is good to do mysql transaction over two different servers (I mean, is there any chances that database will get corrupted by poor implementation of distributed transaction as I read this in some forum).
I searched over internet but I could not find c# code.
Thank you

I suggest you try using the TransactionScope class.
Simply wrap your two sql statements in a transaction scope and they should both commit or rollback together.
using(var transaction = new System.Transactions.TransactionScope())
{
... Add your transactional code here ...
transaction.Complete();
}
I'm not sure this will work but it will give you a place to start and should be simple to test.

Related

TransactionScope transaction = new TransactionScope() VS TransactionScope s = context.Connection.BeginTransaction()

I just want to know if I want to rollback all changes in database if transaction not complete, is there any difference between
using (TransactionScope transaction = new TransactionScope())
and
using (var dbContextTransaction = context.Database.BeginTransaction())
I am confused when read these two:
Connection.BeginTransaction and Entity Framework 4?
and
https://learn.microsoft.com/en-us/ef/ef6/saving/transactions
**note that I use entity framework 4 in my project if its necessary
From Programming Microsoft SQL Server 2012:
There are a number of pain points with explicit transactions. The first difficulty lies in the requirement that every SqlCommand object used to perform updates inside the transaction must have its Transaction property set to the SqlTransaction object returned by BeginTransaction. This means that you must take care to pass along the SqlTransaction object to any place in your code that performs an update, because failing to assign it to the Transaction property of every SqlCommand object in the transaction results in a runtime exception. The issue is compounded when you need to track the SqlTransaction object across multiple method calls that perform updates. It becomes even harder to manage things when these methods need to be flexible enough to work whether or not a transaction is involved or required.
The problem is worse when working with any of the other technologies we'll be covering later that provide abstraction layers over the raw objects. For example, because a SqlDataAdapter actually wraps three distinct SqlCommand objects (for insert, update, and delete), you must dig beneath the data adapter and hook into its three underlying command objects so that you can set their Transaction properties. (We don't generally recommend that you mix and match different data access APIs within your application, but if you must transactionalize updates across a combination of technologies, implicit transactions make it easy.)
The TransactionScope object, introduced as part of a dedicated transaction management API with .NET 2.0 in 2005, lets you code transactions implicitly. This is a superior approach that relieves you from all of the aforementioned burdens associated with explicit transactions. So the guidance here is to always work with implicit transactions whenever possible. You will write less code that is more flexible when you allow the framework to handle transaction management for you. However, it is still also important to understand explicit transactions with the SqlTransaction object, as you might need to integrate with and extend existing code that already uses explicit transactions. Therefore, we will cover both transaction management styles to prepare you for all situations.
The transaction management API offers many more benefits besides implicit transactions. For example, TransactionScope is capable of promoting a lightweight transaction (one associated with a single database) to a distributed transaction automatically, if and when your updates involve changes across multiple databases.
There are two pitfalls with TransactionScope you should be aware of.
First is that it will, by default, create a transaction with SERIALIZABLE isolation level, which, for SQL Server, is a poor choice. So you should always create your TransactionScope like this:
public class TransactionUtils
{
public static TransactionScope CreateTransactionScope()
{
var transactionOptions = new TransactionOptions();
transactionOptions.IsolationLevel = IsolationLevel.ReadCommitted;
transactionOptions.Timeout = TransactionManager.MaximumTimeout;
return new TransactionScope(TransactionScopeOption.Required, transactionOptions);
}
}
See rant here: using new TransactionScope() Considered Harmful
The second is that TransactionScope supports Distributed Transactions. So it will enable you to enlist different connections and even different resource providers in a single transaction. While this is occasionally useful, it's more often a pitfall. If you accidently end up with a distributed transaction you can accidently take a dependency on having a distributed transaction coordinator in your environment. So you should take steps to avoid having a distributed transaction, like shutting down Microsoft Distributed Transaction Coordinator (MSDTC) in your development environment. And ensure that any time you have multiple methods enlisted in a transaction, they don't both have a SqlConnection open at the same time.
While Database. BeginTransaction() is used only for database related operations transaction, System. Transactions. ... TransactionScope for mixing db operations and C# code together in a transaction.
please see Below Links.Hope they help you:
TransactionScope vs Transaction in LINQ to SQL
Database.BeginTransaction vs Transactions.TransactionScope

Rollback changes made to Database in Entity Framework .NET

I am writing unit test cases for testing a framework. The unit test adds and modifies the data in an existing database. I need to rollback all the changes done to database after a test finishes, i.e. delete the rows added and revert the rows modified.
I am using Entity Framework 6 for accessing the database. The underlying database is SQL Server. Is there any support provided by EF6 to achieve this?
Presently I am storing the changes in a list and I refer the this list for cleaning up the database. But using this approach leaves some residue randomly. I am not sure of the reason though, maybe some race condition or something.
Looking for some minimal and smart alternative for it. Thanks in advance :)
you can wrap your test in a transaction and don't commit changes:
using (TransactionScope scope = new TransactionScope()) {
//do your stuff
}
But for unit testing propouses you can use Effort - Entity Framework Unit Testing Tool which provide in-memory database operations.
EDITED to reply last comments
You can use an overloaded TransactionScope contructor to control the IsolationLevel, so you can choose to read uncommited changes or not.
If your proxy isn't inside the Transaction, please, check that the connection string is the same, so ado.net can identify the connection and enlist the connection in the same transaction.
If the connection string is not the same, you probably will need to activate the Distributed Transaction Coordinator. Here you have an explanation how DTC scalation occurs: TransactionScope automatically escalating to MSDTC on some machines?

How to update/delete row in multi user environment

I am new to C# and SQL Server.
I am developing an application using Winforms.
I am using dataset.
In master and details transactions, suppose I retrieve one transaction from the database.
At the same time another user also retrieves the same transaction.
My requirement is when I am changing this transaction no one else should be allowed to update or delete the same transaction.
As dataset is in disconnect mode, how can I achieve the locking mechanism?
using (var transaction = connection.BeginTransaction())
{
adapter.Update(dataSet);
transaction.Commit();
}
If the update is to a small number of rows within a table, SQL server grants a row level lock to the caller. If the change is to a large number of rows, SQL server grants a table level lock. Its all automatic. Hence concurrency is taken care of.
The problem however is that with many users simultaneously working on the same set of rows, chance of a dead lock are high. The new CQRS design pattern promoted by Udi Dahan takes care of that. How ever if your application is small, applying CQRS would be an overkill.
If im correct in assuming you are using C# then you should look into some ORM frameworks as they can handle collisions like this for you or at least alert you when they have happened so you can handle them in your code. So you could for instance inform the user someone else has made a change and refresh their display or merge the changes and save the merged data.
Have a look at entity framework. There are literally loads of tutorials and examples available for you. This should get you started.
http://www.asp.net/entity-framework
http://msdn.microsoft.com/en-us/library/bb386876.aspx
This specifically references data concurrency (its MVC but the principles are the same)
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application

Transactions in .net using c# [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Transactions in .net
I just wanted to know about Transaction in .net using c# language. I have gone through different articles on the net. However, I came to know about transaction theoretically but I wanted to know the exact use of it in real time. For example when exactly should I use transactions in real time. Let's suppose, I am writing code where I am doing some action on the click event of a link. Lets say, I am hitting the SQL connection to get some values. Should I use transaction there? If I am writing simple code, where I fetch values without using sql connection, should I use transactions there? What are the pros and cons of using Transactions. Getting theoritical knowledge is different, but I want to know the exact use of it. When to use when not to use. Can transactions be used in simple code? Any responses or links for even basic stuff about transactions are welcome.
I am hitting the SQL connection to get some values. Should I use
transaction there?
No, there are not need to use transactions, when you are not alter data in database.
What are the pros and cons of using Transactions.
As you said, you have learned various articles, So may be you have figure out the reason of using the transactions. Look all of these in concern of database.
The advantages of three-tier applications in creating scalable and robust applications are made feasible by transaction processing systems. The ability to distribute the components that make up applications amongst separate servers without explicitly having to develop for that architecture is another advantage of transaction server processing. Transaction processing systems also ensure that transactions are atomic, consistent, isolated, and durable. This alleviates the developer from having to support these characteristics explicitly.
Why Do We Need Transaction Processing?
The Advantages Of Transaction Processing
 
Can transactions be used in simple code?
Yes, you can simply write code in C# using ADO.Net. (e.g. SQLTransaction class)
e.g.
SqlConnection db = new SqlConnection("connstringhere");
SqlTransaction transaction;
db.Open();
transaction = db.BeginTransaction();
try
{
new SqlCommand("INSERT INTO TransactionDemo " +
"(Text) VALUES ('Row1');", db, transaction)
.ExecuteNonQuery();
new SqlCommand("INSERT INTO TransactionDemo " +
"(Text) VALUES ('Row2');", db, transaction)
.ExecuteNonQuery();
new SqlCommand("INSERT INTO CrashMeNow VALUES " +
"('Die', 'Die', 'Die');", db, transaction)
.ExecuteNonQuery();
transaction.Commit();
Reference:
Performing a Transaction Using ADO.NET
.NET 2.0 transaction model
Refer this article:
http://www.codeproject.com/Articles/10223/Using-Transactions-in-ADO-NET
This will answer you questions about Transactions.
The essence of transaction is to make sure that one or more changes that represent a single process get to database once and if one of them fail, the others should be reversed. If you are transferring money from one bank account to another, the deduction from one account and the depositing to the other account must be successful altogether. Otherwise, money would be lost in transit
using(SqlConnection conn = new SqlConnection())
{
try
{
conn.Open();
SqlTransaction tran = conn.BeginTransaction();
//command to remove from account A
//command to deposit into account B
tran.Commit(); //both are successful
}
catch(Exception ex)
{
//if error occurred, reverse all actions. By this, your data consistent and correct
tran.Rollback();
}
}
Another alternative is TransactionScope, System.Transactions
If you are serious about using Transactions you can also read some Articles about the TransactionScope class in .NET . It's very simple to implement Transactions this way.
http://simpleverse.wordpress.com/2008/08/05/using-transactionscope-for-handling-transactions/
Example:
using ( var transaction = new TransactionScope() )
{
// My Database Operations. It doesn't matter what database Type
transaction.Complete();
}
generally you as most have suggested should probably be using TransactionScope, although this does come with some bits to be aware of.
using(TransactionScope ts = TransactionUtils.CreateTransactionScope()){
using(SqlConnection conn = new SqlConnection(connString)){
conn.Open();
using(SqlCommand cmd = new SqlCommand("DELETE FROM tableName WHERE somethingorother", conn)){
cmd....
}
using(SqlCommand cmd ....) ...
thingy.Save();//uses another command/connection possibly
}
//all above Sql Calls will be done at this point. all or nothing
ts.Complete();
}
depending on how it is used (and what DB/version you are using), TransactionScope may escalate the transaction to MSDTC, which would need setting up on the machine running the app (dcomcnfg from the run prompt). ( TransactionScope automatically escalating to MSDTC on some machines? )
also worth having a read of this
http://blogs.msdn.com/b/dbrowne/archive/2010/06/03/using-new-transactionscope-considered-harmful.aspx
rather than blankly using a new TransactionScope() - that article suggests making a static method to generate one with some more helpful defaults.
public class TransactionUtils {
public static TransactionScope CreateTransactionScope()
{
var transactionOptions = new TransactionOptions();
transactionOptions.IsolationLevel = IsolationLevel.ReadCommitted;
transactionOptions.Timeout = TransactionManager.MaximumTimeout;
return new TransactionScope(TransactionScopeOption.Required, transactionOptions);
}
}
hth
I can tell you that using transactions depends on the business rules.
Technically, you may use transactions only if you are modifying data (Update, Delete, Insert) on the systems. When you are just getting values from a source and you are 100% sure that no data gets modified/produced, then don't include this step as part of your transaction.
To keep it simple, use transactions if you answer yes to any of these scenarios:
a) Affect more than one table in your click.
b) Affect more than one system in your click. This includes databases located in different servers, even if you have two different instances in the same server it counts as a different system. Web service calls count as another system as well.
c) Have an scenario like: "perform step a, perform step b, if everything OK then return OK else revert step b, revert step a then return error".
Now how to use transactions in real world. Well, if you are using only one database in your model then use the ADO.NET transaction model.
http://adotutorial.blogspot.de/2008/11/transaction-management-in-adonet.html
If you however, are calling different instances of databases in the same server, or if you you are mixing different technologies (SQL, Oracle, Web Services), transaction management will be 1000 times more painful. Then you need to use transaction scope make it a little bit simpler. In C# in .NET 2.0 you have TransactionScope. This is the way that you can tell the run-time to help us manage transactions.
Check this tutorial, it may help.
http://codingcramp.blogspot.de/2009/06/how-to-setup-and-use-transactionscope.html
If you are using microsoft technologies and if you are working on the same computer, then your code wil run fine. However, if you are running in a networked environment, or if you are mixing different vendors, then another key component enter in the play it is called a "Transaction Monitor". If that is your case then you may need to check if Microsoft DTC is enabled in your environment as it will be the default choice used for coordinating your transactions.

Transactions to a SQL Server database from multiple application using NHibernate created with C#

I've created an C# application using NHibernate to select and insert to a SQL Server database created in Database Design Studio Lite and managed with SQL Server Management Studio.
My problem is that when I have the application running on several workstations, the database is not safe for multiple transaction like it is not "thread safe", don't know what to call the problem.
What is simplest way to make my database safe from multiple transactions? I've tried to set "Restrict Access" to SINGLE_USER mode, but that locks the database to the first application that connects to it and leaves all the other applications to fail.
From SQL Server Management Studio I only create tables. I do not select, insert or update the database. All of the this is done from the applications.
I hope that these information I've provided is enough to help me out. Otherwise I'll post some more :)
EDIT
Found out that NHibernate uses the SessionFactory so all transactions are safe :)
Are you using actual transactions when querying, adding, and modifying records?
using (var session = SessionFactory.OpenSession())
using (var tx = session.BeginTransaction())
{
// query or submit changes to session here, calling tx.Commit() at the end if you make changes
}
The default isolation should restrict to read committed, so queries should not be returning any modifications that have not been fully committed yet.

Categories