I am using Transactionscope with linqtosql. I have the following code:
public bool Save(int Id, List<Student> students, List<Subject> subjects)
{
var isDataSaved = false;
using (TransactionScope scope = new TransactionScope())
{
try
{
// Save the students
SaveStudents(students);
// Save the subjects
SaveSubjects(subjects);
scope.Complete();
isDataSaved = true;
}
catch (Exception ex)
{
throw ex;
}
return isDataSaved;
}
}
In both the methods I am using the two tables : Students, Subjects present in the same database. The datacontext object dependency is setup using the constructor as mentioned in the below class:
public class StudentsRepository:IStudentsRepository
{
public StudentsRepository()
{
_dataContext = new SchoollDetailsDataContext(connectionString);
}
}
The same datacontext object is used in both the methods SaveStudents and SaveSubjects.
I am getting an exception : MSDTC on server 'servername' is unavailable.
As per my initial analysis this kind of error will occur where a database operation will be in my local database and another will be in a remote database.
Can anyone help me to know is there anything I am missing here?
You need to turn the MSDTC service on.
Start-->Control Panel --> Administrative Tools --> services.
Find the service Distributed Transaction Coordinator and start it.
By default its startup property is set to Manual so its switched off.
Related
I am using play java 2.5.
I have created a database with following java code.
public OnStartup() throws SQLException {
//demo create database with java code
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/?user=root&password=12345678");
Statement s = con.createStatement();
int Result = s.executeUpdate("CREATE DATABASE recruit3");
}
Module:
public class OnStartupModule extends AbstractModule {
#Override
public void configure() {
bind(OnStartup.class).asEagerSingleton();
}
}
application.conf:
play.modules {
enabled += "be.objectify.deadbolt.java.DeadboltModule"
enabled += modules.CustomDeadboltHook
enabled += modules.OnStartupModule
}
default.driver=com.mysql.jdbc.Driver
default.url="jdbc:mysql://localhost:3306/recruit3"
default.username=root
default.password="12345678"
My question is, why running the web-app creating
error Cannot connect to database [default]
How to fix that, if I don't want to create the database with mysql workbench.
Any suggestion or cannot do this, please tell me.
Thanks for advance.
As well as moving your database keys to the db.default namespace, you should be injecting Database into OnStartup to access the database configured with those properties.
First, add Play's JDBC support to build.sbt.
libraryDependencies += javaJdbc
If you're already running activator, make sure you use the reload command to pick up the changes to the build.
Update your application.conf to place the database configuration into the correct namespace.
db {
default {
driver=com.mysql.jdbc.Driver
url="jdbc:mysql://localhost:3306/recruit3"
username=root
password="12345678"
}
}
Finally, update OnStartup to receive a Database object that will be injected by Play.
import javax.inject.Inject;
import play.db.Database;
public class OnStartup {
#Inject
public OnStartup(final Database db) throws SQLException {
db.withConnection((Connection conn) -> {
final Statement s = con.createStatement();
return s.executeUpdate("CREATE DATABASE recruit3");
});
}
}
This allows you to configure the database one time, in application.conf, instead of hard-coding DB configuration into a class.
You can find more information here.
Your database keys start with default instead of db.default. The correct syntax is something like this:
db {
default {
driver=com.mysql.jdbc.Driver
url="jdbc:mysql://localhost:3306/recruit3"
username=root
password="12345678"
}
}
You already made your class as eager singleton, so it should work
I am trying to create a Merge Replication using RMO Programming which i got from here!
string publisherName = "DataSourceName";
string publicationName = "AdvWorksSalesOrdersMerge";
string publicationDbName = "AdventureWorksDW2008R2";
ReplicationDatabase publicationDb;
MergePublication publication;
// Create a connection to the Publisher.
ServerConnection conn = new ServerConnection(publisherName);
try
{
//Connect to the Publisher.
conn.Connect();
// Enable the database for merge publication.
publicationDb = new ReplicationDatabase(publicationDbName, conn);
if (publicationDb.LoadProperties())
{
if (!publicationDb.EnabledMergePublishing)
{
publicationDb.EnabledMergePublishing = true;
}
}
else
{
// Do something here if the database does not exist.
throw new ApplicationException(String.Format(
"The {0} database does not exist on {1}.",
publicationDb, publisherName));
}
// Set the required properties for the merge publication.
publication = new MergePublication();
publication.ConnectionContext = conn;
publication.Name = publicationName;
publication.DatabaseName = publicationDbName;
// Enable precomputed partitions.
publication.PartitionGroupsOption = PartitionGroupsOption.True;
//Specify the Windows account under which the Snapshot Agent job runs.
// This account will be used for the local connection to the
// Distributor and all agent connections that use Windows Authentication.
publication.SnapshotGenerationAgentProcessSecurity.Login = userid;
publication.SnapshotGenerationAgentProcessSecurity.Password = password;
//Explicitly set the security mode for the Publisher connection
// Windows Authentication (the default).
publication.SnapshotGenerationAgentPublisherSecurity.WindowsAuthentication = true;
//Enable Subscribers to request snapshot generation and filtering.
publication.Attributes |= PublicationAttributes.AllowSubscriberInitiatedSnapshot;
publication.Attributes |= PublicationAttributes.DynamicFilters;
// Enable pull and push subscriptions.
publication.Attributes |= PublicationAttributes.AllowPull;
publication.Attributes |= PublicationAttributes.AllowPush;
if (!publication.IsExistingObject)
{
//Create the merge publication.
publication.Create();
// Create a Snapshot Agent job for the publication.
publication.CreateSnapshotAgent();
}
else
{
throw new ApplicationException(String.Format(
"The {0} publication already exists.", publicationName));
}
}
catch (Exception ex)
{
//Implement custom application error handling here.
throw new Exception(String.Format("The publication {0} could not be created.", publicationName), ex);
}
finally
{
conn.Disconnect();
}
but at this line
publicationDb.EnabledTransPublishing = true;
i am getting error -" An exception occurred while executing a Transact-SQL statement or batch."
So please help me out from this problem ..
waiting for your answers..
You Probably have you answer by now but for those who might be asking the same question. Its because you are using an express version of SQL Server and Publisher/distributors cannot be created in any version of SQl Server Express.
The instance you have in your code there is not a valid instance hence the exception is thrown.
take a look at:
http://msdn.microsoft.com/en-us/library/ms151819(v=sql.105).aspx
and the lines that say
Microsoft SQL Server 2008 Express can serve as a Subscriber for all types of replication, providing a convenient way to distribute data to client applications that use this edition of SQL Server. When using SQL Server Express in a replication topology, keep the following considerations in mind:
SQL Server Express cannot serve as a Publisher or Distributor. However, merge replication allows changes to be replicated in both directions between a Publisher and Subscriber.
Blockquote
I'm using NHibernate 3.1.0 with the MySql Connector 6.3.5. As a general rule my repository methods are wrapped in an NHibernate transaction. However the service or application code calling the repository methods might also require a transaction scope - therefore the mixing of NHibernate transactions with .NET's TransactionScope. A simulated test looks like this:
[Test]
public void CanPerformNestedSave()
{
using (var tx = new TransactionScope())
{
var user = new AdminUser { Email = "user#test.com", Name = "Test User 1", Password = "123" };
using (ISession session = OpenSession())
{
using (var tx = session.BeginTransaction())
{
entity.ModifiedAt = DateTime.Now;
session.SaveOrUpdate(entity);
tx.Commit();
return entity;
}
}
tx.Complete();
}
}
The test fails with the following error:
NHibernate.TransactionException : Begin failed with SQL exception
----> System.InvalidOperationException : Nested transactions are not supported.
I've scoured the web to find a solution to this scenario and hopefully the community on StackOverflow can help.
I've blogged about this here.
In the blog post NServiceBus creates the outer TransactionScope for the handlers and the Nhibernate session and transactions are used inside the handler.
I am trying learn how to best use the Reactive Extensions library and have set up simple test WPF application to view a logging database table. In a ViewModel class I am populating an ObservableCollection with the first 100 log entries from a Linq to Sql DataContext and I'm trying to use Rx to keep the UI responsive.
The following snippet works unless the database is unavailable at which point the app throws an exception and crashes. Where would be the best place to handle database connection exceptions and why are they not handled by the OnError method of the Observer?
ObservableCollection<LogEntry> _logEntries = new ObservableCollection<LogEntry>();
DataContext dataContext = new DataContext( "connection string" );
(from e in dataContext.LogEntries
select e).Take( 100 ).ToObservable()
.SubscribeOn( Scheduler.ThreadPool )
.ObserveOnDispatcher()
.Subscribe( _logEntries.Add, ex => System.Diagnostics.Debug.WriteLine( ex.ToString() ) );
Try this instead of ToObservable:
public static IObservable<T> SafeToObservable(this IEnumerable<T> This)
{
return Observable.Create(subj => {
try {
foreach(var v in This) {
subj.OnNext(v);
}
subj.OnCompleted();
} catch (Exception ex) {
subj.OnError(ex);
}
return Disposable.Empty;
});
}
In general though, this isn't a great use of Rx since the data source isn't very easy to Rx'ify - in fact, the code will execute most of the work on the UI thread, send it out to random worker threads, then send it back (i.e. completely wasted work). Task + Dispatcher.BeginInvoke might suit you better here.
I'm trying to build a layer over NServiceBus to make it simpler for other developers to use.
I'm trying to do without the config file and managed to get the publisher to work:
public class NServiceBusPublisher
{
private IBus _Bus { get; set; }
public void NServiceBusPublisher(string argInputQueue, string argErrorQueue)
{
Configure configure = NServiceBus.Configure.With().DefaultBuilder();
var transport = configure.Configurer.ConfigureComponent<MsmqTransport>(ComponentCallModelEnum.Singleton);
transport.ConfigureProperty(t => t.InputQueue, argInputQueue);
transport.ConfigureProperty(t => t.ErrorQueue, argErrorQueue);
transport.ConfigureProperty(t => t.NumberOfWorkerThreads, 1);
transport.ConfigureProperty(t => t.MaxRetries, 5);
_Bus =
configure
.XmlSerializer()
.MsmqTransport()
.IsTransactional(true)
.PurgeOnStartup(false)
.MsmqSubscriptionStorage()
.UnicastBus()
.ImpersonateSender(false)
.CreateBus()
.Start();
}
public void Publish(NServiceBus.IMessage argMessage)
{
_Bus.Publish(argMessage);
}
}
I also want to have an NServiceBus Subscriber and make it possible for developers to subscribe to any number of message types as long as the message inherits from NServiceBus.IMessage:
public class NServiceBusSubscriber
{
private IBus _Bus { get; set; }
public void NServiceBusSubscriber(string argInputQueue, string argOutputQueue, string argErrorQueue, string messagesAssembly)
{
Configure configure = NServiceBus.Configure.With().DefaultBuilder();
var transport = configure.Configurer.ConfigureComponent<MsmqTransport>(ComponentCallModelEnum.Singleton);
transport.ConfigureProperty(t => t.InputQueue, argInputQueue);
transport.ConfigureProperty(t => t.ErrorQueue, argErrorQueue);
transport.ConfigureProperty(t => t.NumberOfWorkerThreads, 1);
transport.ConfigureProperty(t => t.MaxRetries, 5);
var ucb = configure.Configurer.ConfigureComponent<NServiceBus.Unicast.UnicastBus>(ComponentCallModelEnum.Singleton);
ucb.ConfigureProperty(u => u.MessageOwners, new Dictionary<string,string>()
{
{messagesAssembly, argOutputQueue}
});
_Bus =
configure
.XmlSerializer()
.MsmqTransport()
.IsTransactional(true)
.PurgeOnStartup(false)
.MsmqSubscriptionStorage()
.UnicastBus()
.ImpersonateSender(false)
.DoNotAutoSubscribe()
.CreateBus()
.Start();
}
public void Subscribe<T>() where T : NServiceBus.IMessage
{
_Bus.Subscribe<T>();
}
}
The problem is that I couldn't find any way to attach an event handler to a particular message type.
Could you please help me figure this out?
Its been a while since the question has been asked, so I am not sure if the problem has been solved, but here's one way you can do it using Bus.Subscribe (although as has been said by other respondents this is not the prescribed way of doing it NServiceBus)
Subscribe the to the message type using the subscribe overload
void Subscribe(Type messageType, Predicate<IMessage> condition);
Then you can handle the message in the delegate
private bool Handle(NServiceBus.IMessage nsbMsg)
{
//you get the message instance that you can handle
//return true
}
So, your code would then be
class MySubscriber
{
public IBus Bus {get; set;}
public void Subscribe()
{
Bus.Subscribe(typeof(MyMessage), Handle);
}
public void Handle(NServiceBus.IMessage nsbMsg)
{
var msg = nsbMsg as MyMessage;
//your code
return true;
}
}
However please note that by doing this you have to manage the lifetime of the handler yourself, which otherwise would have been managed for you by NServiceBus using the IOC framework of your choice.
You will also have to pass the reference to IBus explicitly which would be injected for you automatically if you were just implementing the IHandleMessage interface.
An architectural point here is that NSB is a full fledged 'ESB', its not just a messaging layer. Adding another layer over your ESB is IMHO an abstraction too many.
I think you are missing the concept behind NServiceBus.
Based on the code you show I get the impression that you envision services that publish messages and others that process those messages. In my experience most processes do both: they subscribe to events or process incoming commands and in result publish new events and send new commands.
In your setup you would need to have publisher and subscriber instances for each of these message types.
NServiceBus is built for the situation I describe. You configure and start 1 bus instance and that orchestrates the complete application.
If you want to make it easier for developers to use NServiceBus I would concentrate on the configuration part only. In our company I have created a ServicebusConfigurator class that configures NServiceBus according our company standards and extracted that in a framework and a simple extension method for the .NET Core generic host. The only code our developers need to write to create a Windows Service that hosts an NServiceBus endpoint is something like this:
internal static class Program
{
private static int Main(string[] args)
{
return (int)Host.CreateDefaultBuilder(args) //.NET Core generic host
.WithNServiceBus() //configure NServiceBus according to our standards and start it.
.UseTopshelf<Worker>() // use Worker as the actual service doing the work.
.EnableNsbInstallersDuringInstall() // Execute any NServiceBus transport specific installation code during install of the service.
.Run(); // Run the thing.
}
}
Since you are not auto-subscribing the first thing you will need to do is subscribe to the message type via Bus.Subscribe(). Others could do this at the IWantToRunAtStartUp extension point(implement the interface in a class somewhere). From there, each subscriber will implement the IHandleMessages<T> interface. Implementing this interface wires you to a message where "T" is the message type.
When NSB starts up it will scan the local bin dir and find all your interface implementations and wire them up on your behalf internally. From there it will dispatch to the correct handler when a message of that type arrives.
NServiceBus automatically handles the subscription of messages. When you invoke Configure.With()....Start(); NServiceBus will scan to determine which assemblies implement IHandleMessages(SomeMessage) and it will send a subscription request to the publisher.
When you add "DoNotAutoSubscribe", you've got to manually get all messages being handled and do a Bus.Subscribe() for each of them.
Beyond that, NServiceBus will automatically handle the routing of an incoming message to the appropriate handler. In your subscriber code above, are you receiving an error message or are the messages disappearing from the queue?