Transactions with Vapor 4/Fluent - vapor

I'm trying to save 2 related models and would like to use a database transaction for this so that in case of a failure nothing is written to the database.
In Vapor 3 you could use the following:
req.transaction(on: .<#dbid#>) { conn in
// use conn as your connection
}
How can this be done in Vapor 4? Unfortunately, the documentation for transactions doesn't exist for version 4.

It's req.db.transaction to create a new transaction for use. The tests are the best place to look to find examples - e.g. here
(Also an issue on GH at vapor/docs would be great to ensure the docs get written!)

Related

Use other database connection and execute query

In our app, we need to switch to read replica database and read from it for some read-only APIs.
We decided to use the around_action filter for that:
Switch DB to read_replica before the action
Yield
Switching back to master.
We decided to use establish_connection for switching, which did the job but later we noticed that it's not thread-safe i.e it causes our other threads to face "#<ActiveRecord::ConnectionNotEstablished: No connection pool with 'primary' found.>" issue. So this solution would have worked in the case of single-threaded servers.
Later we tried to create a new connection pool, as below which is thread-safe:
databases = Rails.configuration.database_configuration
resolver = ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new(databases)
spec = resolver.spec(:read_replica)
pool = ActiveRecord::ConnectionAdapters::ConnectionPool.new(spec)
pool.with_connection { |conn|
execute SQL query here.
}
The only problem with the above approach is, we can only execute queries using execute method like conn.execute(sql_query) any AR ORM query we execute inside this with_connection block run on the original DB and not read_replica.
Seems like ActiveRecord do have its default connection and it's using it when we run AR ORM queries.
Not sure how can we execute the AR ORM query inside the with_connection block as User.where(id: 1..10).
Please note:
I am aware that we can do this natively in rails 6, need to skip that for now.
I am also aware of the Octopus gem, again need to skip on that.
Appreciate any help, Thanks.

Unable to connect to Neo4j from c# driver Session to fabric database

Using the Neo4j.Driver (4.1.0) I am unable to connect a session to server's configured fabric database. It works fine in the Neo4j Browser. Is there a trick to setting the context to a fabric database?
This times out:
var session = driver.AsyncSession(o => o.WithDatabase("fabric"));
Actual database names work fine.
Does the c# driver not support setting the Session context to a fabric database?
I'm trying to execute something like the following:
use fabric.graph(0)
match ...
set...
I found a workaround by co-opting a sub-query as follows, but it seems that setting the session context would make more sense.
use fabric
call {
use fabric.graph(0)
match ...
set ...
return 0
}
return 0
I've not yet worked with fabric. But I have worked with clusters. You can only add nodes/edges to the one Neo4j database that has a WRITE role. To do this you need a small function to query the routing table and determine the write database. Here's the key query:
CALL dbms.cluster.routing.getRoutingTable({}) YIELD ttl, servers UNWIND servers as server with server where server.role='WRITE' RETURN server.addresses
You then address your write query to that specific database.

How to use Rails connection which is manually checkout

I have code which where I manually checkout a connection like
connection = User.connection_pool.checkout
Now, I wish to use this connection to query any record in DB
is there a way to achieve this.
I'm not sure what I'm suppose to do with the connection, I just obtained other then checking it back in
So ideally I want the code do this.
connection = User.connection_pool.checkout
... ## query
User.connection_pool.checkin(connection)
Note: Please don't answer me to use with_connection, the point of this question is to manage checkout/checkin manually.
Any clue ??
Well in Rails 4.2 the way to achieve this is ..
connection = User.connection_pool.checkout
User.connection_pool.instance_variable_get(:'#reserved_connections')[Thread.current.object_id] ||= conn
User.first
User.connection_pool.checkin(conn)
This Works.
conn = Model.connection_pool.checkout
#records = conn.execute("call some_stored_procedure(args)")
Model.connection_pool.checkin(conn)
I specifically gave the example of executing a stored procedure because no other methods were able to execute SPs. This question actually helped my task out!
You can also execute other queries as well, like:
conn.execute("select attr1, attr2 from models")

neo4jrb how to reset transaction timeout of an open transaction

Currently using neo4j-community-2.1.7
I understand that the facility has been included in this version.
Have been unable to find any reference to it in the ruby docs.
Would appreciate it very much if I may have some direction on how to reset the timeout using neo4jrb.
Regards
Ross
I am unaware of a way to reset the transaction timeout of an open transaction. Maybe someone more familiar with transactions in the Java API can clarify.
If you want to change the transaction timeout length at boot, that's handled in neo4j-server.properties as described at http://neo4j.com/docs/stable/server-configuration.html.
Within Neo4j-core, if using Neo4j-community or Neo4j-enterprise (and therefore Neo4j Embedded) the code suggests that you can specify a config file by giving a third argument to Neo4j::Session.open, a hash that contains config options. That method, if given :embedded_db as its first arg, will call Neo4j::Embedded#initialize and give that hash as an argument. If you do something like this:
Neo4j::Session.open(:embedded_db, 'path_to_db', properties_file: 'path_and_filename_to_neo4j-server.properties')
It will eventually use that properties file:
db_service.loadPropertiesFromFile(properties_file) if properties_file
This is not demonstrated in any of the specs, unfortunately, but you can see it in the initialize and start methods at https://github.com/neo4jrb/neo4j-core/blob/230d69371ed6bf39297786155ef4f3b1831dac08/lib/neo4j-embedded/embedded_session.rb.
RE: COMMENT INFO
If you're using :server_db, you don't need to include the neo4j-community gem. It isn't loaded, it isn't compatible with Neo4j in Server mode.
That's the first time I've seen the link you provided, good to know that's there. We don't expose a way to do that in Neo4j.rb and won't because it would require some threading magic that we can't support. If you want to do it manually, the best I can tell you is that you can get a current transaction ID this way:
tx = Neo4j::Transaction.new
# do stuff and before your long-running query...
tx.resource_data[:commit].split('/')[-2]
That will return the transaction number that you can use in POST as described in their support doc.
If you'd like help troubleshooting your long-running Cypher query, I'm sure people on SO will help.

neo4j - Commands withing transaction

Well I am writing server plugin. I want to know what should all commands come with in transaction ?
Like, is it a good programming to begin transaction at the beginning of function and end transaction before return or we should do it in some otherway.
One more thing : Is there any limitations on, what all we can write withing transaction.
Can I write anything in java withing transaction like for loop, while loop , if , else ..
Thanks
Amit Aggarwal
If you are using a release < Neo4j 2.0 then only operations that modify the database need to be wrapped in a transaction. In Neo4j 2.0, any operation that accesses the graph needs to be wrapped in a transaction.
You can definitely use loops/branches etc.

Resources